Conditions | 7 |
Paths | 4 |
Total Lines | 12570 |
Code Lines | 3502 |
Lines | 4 |
Ratio | 0.03 % |
Changes | 0 |
Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.
For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.
Commonly applied refactorings include:
If many parameters/temporary variables are present:
1 | ///////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
||
22 | ;(function() { |
||
23 | |||
24 | /** Used as a safe reference for `undefined` in pre-ES5 environments. */ |
||
25 | var undefined; |
||
26 | |||
27 | /** Used as the semantic version number. */ |
||
28 | var VERSION = '3.10.1'; |
||
29 | |||
30 | /** Used to compose bitmasks for wrapper metadata. */ |
||
31 | var BIND_FLAG = 1, |
||
32 | BIND_KEY_FLAG = 2, |
||
33 | CURRY_BOUND_FLAG = 4, |
||
34 | CURRY_FLAG = 8, |
||
35 | CURRY_RIGHT_FLAG = 16, |
||
36 | PARTIAL_FLAG = 32, |
||
37 | PARTIAL_RIGHT_FLAG = 64, |
||
38 | ARY_FLAG = 128, |
||
39 | REARG_FLAG = 256; |
||
40 | |||
41 | /** Used as default options for `_.trunc`. */ |
||
42 | var DEFAULT_TRUNC_LENGTH = 30, |
||
43 | DEFAULT_TRUNC_OMISSION = '...'; |
||
44 | |||
45 | /** Used to detect when a function becomes hot. */ |
||
46 | var HOT_COUNT = 150, |
||
47 | HOT_SPAN = 16; |
||
48 | |||
49 | /** Used as the size to enable large array optimizations. */ |
||
50 | var LARGE_ARRAY_SIZE = 200; |
||
51 | |||
52 | /** Used to indicate the type of lazy iteratees. */ |
||
53 | var LAZY_FILTER_FLAG = 1, |
||
54 | LAZY_MAP_FLAG = 2; |
||
55 | |||
56 | /** Used as the `TypeError` message for "Functions" methods. */ |
||
57 | var FUNC_ERROR_TEXT = 'Expected a function'; |
||
58 | |||
59 | /** Used as the internal argument placeholder. */ |
||
60 | var PLACEHOLDER = '__lodash_placeholder__'; |
||
61 | |||
62 | /** `Object#toString` result references. */ |
||
63 | var argsTag = '[object Arguments]', |
||
64 | arrayTag = '[object Array]', |
||
65 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
||
66 | // Patched from https://github.com/lodash/lodash/blob/95bc54a3ddc7a25f5e134f5b376a0d1d96118f49/lodash.js#L86-L108 |
||
67 | asyncTag = '[object AsyncFunction]', |
||
68 | genTag = '[object GeneratorFunction]', |
||
69 | proxyTag = '[object Proxy]', |
||
70 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
||
71 | boolTag = '[object Boolean]', |
||
72 | dateTag = '[object Date]', |
||
73 | errorTag = '[object Error]', |
||
74 | funcTag = '[object Function]', |
||
75 | mapTag = '[object Map]', |
||
76 | numberTag = '[object Number]', |
||
77 | objectTag = '[object Object]', |
||
78 | regexpTag = '[object RegExp]', |
||
79 | setTag = '[object Set]', |
||
80 | stringTag = '[object String]', |
||
81 | weakMapTag = '[object WeakMap]'; |
||
82 | |||
83 | var arrayBufferTag = '[object ArrayBuffer]', |
||
84 | float32Tag = '[object Float32Array]', |
||
85 | float64Tag = '[object Float64Array]', |
||
86 | int8Tag = '[object Int8Array]', |
||
87 | int16Tag = '[object Int16Array]', |
||
88 | int32Tag = '[object Int32Array]', |
||
89 | uint8Tag = '[object Uint8Array]', |
||
90 | uint8ClampedTag = '[object Uint8ClampedArray]', |
||
91 | uint16Tag = '[object Uint16Array]', |
||
92 | uint32Tag = '[object Uint32Array]'; |
||
93 | |||
94 | /** Used to match empty string literals in compiled template source. */ |
||
95 | var reEmptyStringLeading = /\b__p \+= '';/g, |
||
96 | reEmptyStringMiddle = /\b(__p \+=) '' \+/g, |
||
97 | reEmptyStringTrailing = /(__e\(.*?\)|\b__t\)) \+\n'';/g; |
||
98 | |||
99 | /** Used to match HTML entities and HTML characters. */ |
||
100 | var reEscapedHtml = /&(?:amp|lt|gt|quot|#39|#96);/g, |
||
101 | reUnescapedHtml = /[&<>"'`]/g, |
||
102 | reHasEscapedHtml = RegExp(reEscapedHtml.source), |
||
103 | reHasUnescapedHtml = RegExp(reUnescapedHtml.source); |
||
104 | |||
105 | /** Used to match template delimiters. */ |
||
106 | var reEscape = /<%-([\s\S]+?)%>/g, |
||
107 | reEvaluate = /<%([\s\S]+?)%>/g, |
||
108 | reInterpolate = /<%=([\s\S]+?)%>/g; |
||
109 | |||
110 | /** Used to match property names within property paths. */ |
||
111 | var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\n\\]|\\.)*?\1)\]/, |
||
112 | reIsPlainProp = /^\w*$/, |
||
113 | rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\n\\]|\\.)*?)\2)\]/g; |
||
114 | |||
115 | /** |
||
116 | * Used to match `RegExp` [syntax characters](http://ecma-international.org/ecma-262/6.0/#sec-patterns) |
||
117 | * and those outlined by [`EscapeRegExpPattern`](http://ecma-international.org/ecma-262/6.0/#sec-escaperegexppattern). |
||
118 | */ |
||
119 | var reRegExpChars = /^[:!,]|[\\^$.*+?()[\]{}|\/]|(^[0-9a-fA-Fnrtuvx])|([\n\r\u2028\u2029])/g, |
||
120 | reHasRegExpChars = RegExp(reRegExpChars.source); |
||
121 | |||
122 | /** Used to match [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks). */ |
||
123 | var reComboMark = /[\u0300-\u036f\ufe20-\ufe23]/g; |
||
124 | |||
125 | /** Used to match backslashes in property paths. */ |
||
126 | var reEscapeChar = /\\(\\)?/g; |
||
127 | |||
128 | /** Used to match [ES template delimiters](http://ecma-international.org/ecma-262/6.0/#sec-template-literal-lexical-components). */ |
||
129 | var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g; |
||
130 | |||
131 | /** Used to match `RegExp` flags from their coerced string values. */ |
||
132 | var reFlags = /\w*$/; |
||
133 | |||
134 | /** Used to detect hexadecimal string values. */ |
||
135 | var reHasHexPrefix = /^0[xX]/; |
||
136 | |||
137 | /** Used to detect host constructors (Safari > 5). */ |
||
138 | var reIsHostCtor = /^\[object .+?Constructor\]$/; |
||
139 | |||
140 | /** Used to detect unsigned integer values. */ |
||
141 | var reIsUint = /^\d+$/; |
||
142 | |||
143 | /** Used to match latin-1 supplementary letters (excluding mathematical operators). */ |
||
144 | var reLatin1 = /[\xc0-\xd6\xd8-\xde\xdf-\xf6\xf8-\xff]/g; |
||
145 | |||
146 | /** Used to ensure capturing order of template delimiters. */ |
||
147 | var reNoMatch = /($^)/; |
||
148 | |||
149 | /** Used to match unescaped characters in compiled string literals. */ |
||
150 | var reUnescapedString = /['\n\r\u2028\u2029\\]/g; |
||
151 | |||
152 | /** Used to match words to create compound words. */ |
||
153 | var reWords = (function() { |
||
154 | var upper = '[A-Z\\xc0-\\xd6\\xd8-\\xde]', |
||
155 | lower = '[a-z\\xdf-\\xf6\\xf8-\\xff]+'; |
||
156 | |||
157 | return RegExp(upper + '+(?=' + upper + lower + ')|' + upper + '?' + lower + '|' + upper + '+|[0-9]+', 'g'); |
||
158 | }()); |
||
159 | |||
160 | /** Used to assign default `context` object properties. */ |
||
161 | var contextProps = [ |
||
162 | 'Array', 'ArrayBuffer', 'Date', 'Error', 'Float32Array', 'Float64Array', |
||
163 | 'Function', 'Int8Array', 'Int16Array', 'Int32Array', 'Math', 'Number', |
||
164 | 'Object', 'RegExp', 'Set', 'String', '_', 'clearTimeout', 'isFinite', |
||
165 | 'parseFloat', 'parseInt', 'setTimeout', 'TypeError', 'Uint8Array', |
||
166 | 'Uint8ClampedArray', 'Uint16Array', 'Uint32Array', 'WeakMap' |
||
167 | ]; |
||
168 | |||
169 | /** Used to fix the JScript `[[DontEnum]]` bug. */ |
||
170 | var shadowProps = [ |
||
171 | 'constructor', 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable', |
||
172 | 'toLocaleString', 'toString', 'valueOf' |
||
173 | ]; |
||
174 | |||
175 | /** Used to make template sourceURLs easier to identify. */ |
||
176 | var templateCounter = -1; |
||
177 | |||
178 | /** Used to identify `toStringTag` values of typed arrays. */ |
||
179 | var typedArrayTags = {}; |
||
180 | typedArrayTags[float32Tag] = typedArrayTags[float64Tag] = |
||
181 | typedArrayTags[int8Tag] = typedArrayTags[int16Tag] = |
||
182 | typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] = |
||
183 | typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] = |
||
184 | typedArrayTags[uint32Tag] = true; |
||
185 | typedArrayTags[argsTag] = typedArrayTags[arrayTag] = |
||
186 | typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] = |
||
187 | typedArrayTags[dateTag] = typedArrayTags[errorTag] = |
||
188 | typedArrayTags[funcTag] = typedArrayTags[mapTag] = |
||
189 | typedArrayTags[numberTag] = typedArrayTags[objectTag] = |
||
190 | typedArrayTags[regexpTag] = typedArrayTags[setTag] = |
||
191 | typedArrayTags[stringTag] = typedArrayTags[weakMapTag] = false; |
||
192 | |||
193 | /** Used to identify `toStringTag` values supported by `_.clone`. */ |
||
194 | var cloneableTags = {}; |
||
195 | cloneableTags[argsTag] = cloneableTags[arrayTag] = |
||
196 | cloneableTags[arrayBufferTag] = cloneableTags[boolTag] = |
||
197 | cloneableTags[dateTag] = cloneableTags[float32Tag] = |
||
198 | cloneableTags[float64Tag] = cloneableTags[int8Tag] = |
||
199 | cloneableTags[int16Tag] = cloneableTags[int32Tag] = |
||
200 | cloneableTags[numberTag] = cloneableTags[objectTag] = |
||
201 | cloneableTags[regexpTag] = cloneableTags[stringTag] = |
||
202 | cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] = |
||
203 | cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true; |
||
204 | cloneableTags[errorTag] = cloneableTags[funcTag] = |
||
205 | cloneableTags[mapTag] = cloneableTags[setTag] = |
||
206 | cloneableTags[weakMapTag] = false; |
||
207 | |||
208 | /** Used to map latin-1 supplementary letters to basic latin letters. */ |
||
209 | var deburredLetters = { |
||
210 | '\xc0': 'A', '\xc1': 'A', '\xc2': 'A', '\xc3': 'A', '\xc4': 'A', '\xc5': 'A', |
||
211 | '\xe0': 'a', '\xe1': 'a', '\xe2': 'a', '\xe3': 'a', '\xe4': 'a', '\xe5': 'a', |
||
212 | '\xc7': 'C', '\xe7': 'c', |
||
213 | '\xd0': 'D', '\xf0': 'd', |
||
214 | '\xc8': 'E', '\xc9': 'E', '\xca': 'E', '\xcb': 'E', |
||
215 | '\xe8': 'e', '\xe9': 'e', '\xea': 'e', '\xeb': 'e', |
||
216 | '\xcC': 'I', '\xcd': 'I', '\xce': 'I', '\xcf': 'I', |
||
217 | '\xeC': 'i', '\xed': 'i', '\xee': 'i', '\xef': 'i', |
||
218 | '\xd1': 'N', '\xf1': 'n', |
||
219 | '\xd2': 'O', '\xd3': 'O', '\xd4': 'O', '\xd5': 'O', '\xd6': 'O', '\xd8': 'O', |
||
220 | '\xf2': 'o', '\xf3': 'o', '\xf4': 'o', '\xf5': 'o', '\xf6': 'o', '\xf8': 'o', |
||
221 | '\xd9': 'U', '\xda': 'U', '\xdb': 'U', '\xdc': 'U', |
||
222 | '\xf9': 'u', '\xfa': 'u', '\xfb': 'u', '\xfc': 'u', |
||
223 | '\xdd': 'Y', '\xfd': 'y', '\xff': 'y', |
||
224 | '\xc6': 'Ae', '\xe6': 'ae', |
||
225 | '\xde': 'Th', '\xfe': 'th', |
||
226 | '\xdf': 'ss' |
||
227 | }; |
||
228 | |||
229 | /** Used to map characters to HTML entities. */ |
||
230 | var htmlEscapes = { |
||
231 | '&': '&', |
||
232 | '<': '<', |
||
233 | '>': '>', |
||
234 | '"': '"', |
||
235 | "'": ''', |
||
236 | '`': '`' |
||
237 | }; |
||
238 | |||
239 | /** Used to map HTML entities to characters. */ |
||
240 | var htmlUnescapes = { |
||
241 | '&': '&', |
||
242 | '<': '<', |
||
243 | '>': '>', |
||
244 | '"': '"', |
||
245 | ''': "'", |
||
246 | '`': '`' |
||
247 | }; |
||
248 | |||
249 | /** Used to determine if values are of the language type `Object`. */ |
||
250 | var objectTypes = { |
||
251 | 'function': true, |
||
252 | 'object': true |
||
253 | }; |
||
254 | |||
255 | /** Used to escape characters for inclusion in compiled regexes. */ |
||
256 | var regexpEscapes = { |
||
257 | '0': 'x30', '1': 'x31', '2': 'x32', '3': 'x33', '4': 'x34', |
||
258 | '5': 'x35', '6': 'x36', '7': 'x37', '8': 'x38', '9': 'x39', |
||
259 | 'A': 'x41', 'B': 'x42', 'C': 'x43', 'D': 'x44', 'E': 'x45', 'F': 'x46', |
||
260 | 'a': 'x61', 'b': 'x62', 'c': 'x63', 'd': 'x64', 'e': 'x65', 'f': 'x66', |
||
261 | 'n': 'x6e', 'r': 'x72', 't': 'x74', 'u': 'x75', 'v': 'x76', 'x': 'x78' |
||
262 | }; |
||
263 | |||
264 | /** Used to escape characters for inclusion in compiled string literals. */ |
||
265 | var stringEscapes = { |
||
266 | '\\': '\\', |
||
267 | "'": "'", |
||
268 | '\n': 'n', |
||
269 | '\r': 'r', |
||
270 | '\u2028': 'u2028', |
||
271 | '\u2029': 'u2029' |
||
272 | }; |
||
273 | |||
274 | /** Detect free variable `exports`. */ |
||
275 | var freeExports = objectTypes[typeof exports] && exports && !exports.nodeType && exports; |
||
276 | |||
277 | /** Detect free variable `module`. */ |
||
278 | var freeModule = objectTypes[typeof module] && module && !module.nodeType && module; |
||
279 | |||
280 | /** Detect free variable `global` from Node.js. */ |
||
281 | var freeGlobal = freeExports && freeModule && typeof global == 'object' && global && global.Object && global; |
||
282 | |||
283 | /** Detect free variable `self`. */ |
||
284 | var freeSelf = objectTypes[typeof self] && self && self.Object && self; |
||
|
|||
285 | |||
286 | /** Detect free variable `window`. */ |
||
287 | var freeWindow = objectTypes[typeof window] && window && window.Object && window; |
||
288 | |||
289 | /** Detect the popular CommonJS extension `module.exports`. */ |
||
290 | var moduleExports = freeModule && freeModule.exports === freeExports && freeExports; |
||
291 | |||
292 | /** |
||
293 | * Used as a reference to the global object. |
||
294 | * |
||
295 | * The `this` value is used if it's the global object to avoid Greasemonkey's |
||
296 | * restricted `window` object, otherwise the `window` object is used. |
||
297 | */ |
||
298 | var root = freeGlobal || ((freeWindow !== (this && this.window)) && freeWindow) || freeSelf || this; |
||
299 | |||
300 | /*--------------------------------------------------------------------------*/ |
||
301 | |||
302 | /** |
||
303 | * The base implementation of `compareAscending` which compares values and |
||
304 | * sorts them in ascending order without guaranteeing a stable sort. |
||
305 | * |
||
306 | * @private |
||
307 | * @param {*} value The value to compare. |
||
308 | * @param {*} other The other value to compare. |
||
309 | * @returns {number} Returns the sort order indicator for `value`. |
||
310 | */ |
||
311 | function baseCompareAscending(value, other) { |
||
312 | if (value !== other) { |
||
313 | var valIsNull = value === null, |
||
314 | valIsUndef = value === undefined, |
||
315 | valIsReflexive = value === value; |
||
316 | |||
317 | var othIsNull = other === null, |
||
318 | othIsUndef = other === undefined, |
||
319 | othIsReflexive = other === other; |
||
320 | |||
321 | if ((value > other && !othIsNull) || !valIsReflexive || |
||
322 | (valIsNull && !othIsUndef && othIsReflexive) || |
||
323 | (valIsUndef && othIsReflexive)) { |
||
324 | return 1; |
||
325 | } |
||
326 | if ((value < other && !valIsNull) || !othIsReflexive || |
||
327 | (othIsNull && !valIsUndef && valIsReflexive) || |
||
328 | (othIsUndef && valIsReflexive)) { |
||
329 | return -1; |
||
330 | } |
||
331 | } |
||
332 | return 0; |
||
333 | } |
||
334 | |||
335 | /** |
||
336 | * The base implementation of `_.findIndex` and `_.findLastIndex` without |
||
337 | * support for callback shorthands and `this` binding. |
||
338 | * |
||
339 | * @private |
||
340 | * @param {Array} array The array to search. |
||
341 | * @param {Function} predicate The function invoked per iteration. |
||
342 | * @param {boolean} [fromRight] Specify iterating from right to left. |
||
343 | * @returns {number} Returns the index of the matched value, else `-1`. |
||
344 | */ |
||
345 | function baseFindIndex(array, predicate, fromRight) { |
||
346 | var length = array.length, |
||
347 | index = fromRight ? length : -1; |
||
348 | |||
349 | while ((fromRight ? index-- : ++index < length)) { |
||
350 | if (predicate(array[index], index, array)) { |
||
351 | return index; |
||
352 | } |
||
353 | } |
||
354 | return -1; |
||
355 | } |
||
356 | |||
357 | /** |
||
358 | * The base implementation of `_.indexOf` without support for binary searches. |
||
359 | * |
||
360 | * @private |
||
361 | * @param {Array} array The array to search. |
||
362 | * @param {*} value The value to search for. |
||
363 | * @param {number} fromIndex The index to search from. |
||
364 | * @returns {number} Returns the index of the matched value, else `-1`. |
||
365 | */ |
||
366 | function baseIndexOf(array, value, fromIndex) { |
||
367 | if (value !== value) { |
||
368 | return indexOfNaN(array, fromIndex); |
||
369 | } |
||
370 | var index = fromIndex - 1, |
||
371 | length = array.length; |
||
372 | |||
373 | while (++index < length) { |
||
374 | if (array[index] === value) { |
||
375 | return index; |
||
376 | } |
||
377 | } |
||
378 | return -1; |
||
379 | } |
||
380 | |||
381 | /** |
||
382 | * The base implementation of `_.isFunction` without support for environments |
||
383 | * with incorrect `typeof` results. |
||
384 | * |
||
385 | * @private |
||
386 | * @param {*} value The value to check. |
||
387 | * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. |
||
388 | */ |
||
389 | function baseIsFunction(value) { |
||
390 | // Avoid a Chakra JIT bug in compatibility modes of IE 11. |
||
391 | // See https://github.com/jashkenas/underscore/issues/1621 for more details. |
||
392 | return typeof value == 'function' || false; |
||
393 | } |
||
394 | |||
395 | /** |
||
396 | * Converts `value` to a string if it's not one. An empty string is returned |
||
397 | * for `null` or `undefined` values. |
||
398 | * |
||
399 | * @private |
||
400 | * @param {*} value The value to process. |
||
401 | * @returns {string} Returns the string. |
||
402 | */ |
||
403 | function baseToString(value) { |
||
404 | return value == null ? '' : (value + ''); |
||
405 | } |
||
406 | |||
407 | /** |
||
408 | * Used by `_.trim` and `_.trimLeft` to get the index of the first character |
||
409 | * of `string` that is not found in `chars`. |
||
410 | * |
||
411 | * @private |
||
412 | * @param {string} string The string to inspect. |
||
413 | * @param {string} chars The characters to find. |
||
414 | * @returns {number} Returns the index of the first character not found in `chars`. |
||
415 | */ |
||
416 | function charsLeftIndex(string, chars) { |
||
417 | var index = -1, |
||
418 | length = string.length; |
||
419 | |||
420 | while (++index < length && chars.indexOf(string.charAt(index)) > -1) {} |
||
421 | return index; |
||
422 | } |
||
423 | |||
424 | /** |
||
425 | * Used by `_.trim` and `_.trimRight` to get the index of the last character |
||
426 | * of `string` that is not found in `chars`. |
||
427 | * |
||
428 | * @private |
||
429 | * @param {string} string The string to inspect. |
||
430 | * @param {string} chars The characters to find. |
||
431 | * @returns {number} Returns the index of the last character not found in `chars`. |
||
432 | */ |
||
433 | function charsRightIndex(string, chars) { |
||
434 | var index = string.length; |
||
435 | |||
436 | while (index-- && chars.indexOf(string.charAt(index)) > -1) {} |
||
437 | return index; |
||
438 | } |
||
439 | |||
440 | /** |
||
441 | * Used by `_.sortBy` to compare transformed elements of a collection and stable |
||
442 | * sort them in ascending order. |
||
443 | * |
||
444 | * @private |
||
445 | * @param {Object} object The object to compare. |
||
446 | * @param {Object} other The other object to compare. |
||
447 | * @returns {number} Returns the sort order indicator for `object`. |
||
448 | */ |
||
449 | function compareAscending(object, other) { |
||
450 | return baseCompareAscending(object.criteria, other.criteria) || (object.index - other.index); |
||
451 | } |
||
452 | |||
453 | /** |
||
454 | * Used by `_.sortByOrder` to compare multiple properties of a value to another |
||
455 | * and stable sort them. |
||
456 | * |
||
457 | * If `orders` is unspecified, all valuess are sorted in ascending order. Otherwise, |
||
458 | * a value is sorted in ascending order if its corresponding order is "asc", and |
||
459 | * descending if "desc". |
||
460 | * |
||
461 | * @private |
||
462 | * @param {Object} object The object to compare. |
||
463 | * @param {Object} other The other object to compare. |
||
464 | * @param {boolean[]} orders The order to sort by for each property. |
||
465 | * @returns {number} Returns the sort order indicator for `object`. |
||
466 | */ |
||
467 | function compareMultiple(object, other, orders) { |
||
468 | var index = -1, |
||
469 | objCriteria = object.criteria, |
||
470 | othCriteria = other.criteria, |
||
471 | length = objCriteria.length, |
||
472 | ordersLength = orders.length; |
||
473 | |||
474 | while (++index < length) { |
||
475 | var result = baseCompareAscending(objCriteria[index], othCriteria[index]); |
||
476 | if (result) { |
||
477 | if (index >= ordersLength) { |
||
478 | return result; |
||
479 | } |
||
480 | var order = orders[index]; |
||
481 | return result * ((order === 'asc' || order === true) ? 1 : -1); |
||
482 | } |
||
483 | } |
||
484 | // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications |
||
485 | // that causes it, under certain circumstances, to provide the same value for |
||
486 | // `object` and `other`. See https://github.com/jashkenas/underscore/pull/1247 |
||
487 | // for more details. |
||
488 | // |
||
489 | // This also ensures a stable sort in V8 and other engines. |
||
490 | // See https://code.google.com/p/v8/issues/detail?id=90 for more details. |
||
491 | return object.index - other.index; |
||
492 | } |
||
493 | |||
494 | /** |
||
495 | * Used by `_.deburr` to convert latin-1 supplementary letters to basic latin letters. |
||
496 | * |
||
497 | * @private |
||
498 | * @param {string} letter The matched letter to deburr. |
||
499 | * @returns {string} Returns the deburred letter. |
||
500 | */ |
||
501 | function deburrLetter(letter) { |
||
502 | return deburredLetters[letter]; |
||
503 | } |
||
504 | |||
505 | /** |
||
506 | * Used by `_.escape` to convert characters to HTML entities. |
||
507 | * |
||
508 | * @private |
||
509 | * @param {string} chr The matched character to escape. |
||
510 | * @returns {string} Returns the escaped character. |
||
511 | */ |
||
512 | function escapeHtmlChar(chr) { |
||
513 | return htmlEscapes[chr]; |
||
514 | } |
||
515 | |||
516 | /** |
||
517 | * Used by `_.escapeRegExp` to escape characters for inclusion in compiled regexes. |
||
518 | * |
||
519 | * @private |
||
520 | * @param {string} chr The matched character to escape. |
||
521 | * @param {string} leadingChar The capture group for a leading character. |
||
522 | * @param {string} whitespaceChar The capture group for a whitespace character. |
||
523 | * @returns {string} Returns the escaped character. |
||
524 | */ |
||
525 | function escapeRegExpChar(chr, leadingChar, whitespaceChar) { |
||
526 | if (leadingChar) { |
||
527 | chr = regexpEscapes[chr]; |
||
528 | } else if (whitespaceChar) { |
||
529 | chr = stringEscapes[chr]; |
||
530 | } |
||
531 | return '\\' + chr; |
||
532 | } |
||
533 | |||
534 | /** |
||
535 | * Used by `_.template` to escape characters for inclusion in compiled string literals. |
||
536 | * |
||
537 | * @private |
||
538 | * @param {string} chr The matched character to escape. |
||
539 | * @returns {string} Returns the escaped character. |
||
540 | */ |
||
541 | function escapeStringChar(chr) { |
||
542 | return '\\' + stringEscapes[chr]; |
||
543 | } |
||
544 | |||
545 | /** |
||
546 | * Gets the index at which the first occurrence of `NaN` is found in `array`. |
||
547 | * |
||
548 | * @private |
||
549 | * @param {Array} array The array to search. |
||
550 | * @param {number} fromIndex The index to search from. |
||
551 | * @param {boolean} [fromRight] Specify iterating from right to left. |
||
552 | * @returns {number} Returns the index of the matched `NaN`, else `-1`. |
||
553 | */ |
||
554 | function indexOfNaN(array, fromIndex, fromRight) { |
||
555 | var length = array.length, |
||
556 | index = fromIndex + (fromRight ? 0 : -1); |
||
557 | |||
558 | while ((fromRight ? index-- : ++index < length)) { |
||
559 | var other = array[index]; |
||
560 | if (other !== other) { |
||
561 | return index; |
||
562 | } |
||
563 | } |
||
564 | return -1; |
||
565 | } |
||
566 | |||
567 | /** |
||
568 | * Checks if `value` is a host object in IE < 9. |
||
569 | * |
||
570 | * @private |
||
571 | * @param {*} value The value to check. |
||
572 | * @returns {boolean} Returns `true` if `value` is a host object, else `false`. |
||
573 | */ |
||
574 | var isHostObject = (function() { |
||
575 | try { |
||
576 | Object({ 'toString': 0 } + ''); |
||
577 | } catch(e) { |
||
578 | return function() { return false; }; |
||
579 | } |
||
580 | return function(value) { |
||
581 | // IE < 9 presents many host objects as `Object` objects that can coerce |
||
582 | // to strings despite having improperly defined `toString` methods. |
||
583 | return typeof value.toString != 'function' && typeof (value + '') == 'string'; |
||
584 | }; |
||
585 | }()); |
||
586 | |||
587 | /** |
||
588 | * Checks if `value` is object-like. |
||
589 | * |
||
590 | * @private |
||
591 | * @param {*} value The value to check. |
||
592 | * @returns {boolean} Returns `true` if `value` is object-like, else `false`. |
||
593 | */ |
||
594 | function isObjectLike(value) { |
||
595 | return !!value && typeof value == 'object'; |
||
596 | } |
||
597 | |||
598 | /** |
||
599 | * Used by `trimmedLeftIndex` and `trimmedRightIndex` to determine if a |
||
600 | * character code is whitespace. |
||
601 | * |
||
602 | * @private |
||
603 | * @param {number} charCode The character code to inspect. |
||
604 | * @returns {boolean} Returns `true` if `charCode` is whitespace, else `false`. |
||
605 | */ |
||
606 | function isSpace(charCode) { |
||
607 | return ((charCode <= 160 && (charCode >= 9 && charCode <= 13) || charCode == 32 || charCode == 160) || charCode == 5760 || charCode == 6158 || |
||
608 | (charCode >= 8192 && (charCode <= 8202 || charCode == 8232 || charCode == 8233 || charCode == 8239 || charCode == 8287 || charCode == 12288 || charCode == 65279))); |
||
609 | } |
||
610 | |||
611 | /** |
||
612 | * Replaces all `placeholder` elements in `array` with an internal placeholder |
||
613 | * and returns an array of their indexes. |
||
614 | * |
||
615 | * @private |
||
616 | * @param {Array} array The array to modify. |
||
617 | * @param {*} placeholder The placeholder to replace. |
||
618 | * @returns {Array} Returns the new array of placeholder indexes. |
||
619 | */ |
||
620 | function replaceHolders(array, placeholder) { |
||
621 | var index = -1, |
||
622 | length = array.length, |
||
623 | resIndex = -1, |
||
624 | result = []; |
||
625 | |||
626 | while (++index < length) { |
||
627 | if (array[index] === placeholder) { |
||
628 | array[index] = PLACEHOLDER; |
||
629 | result[++resIndex] = index; |
||
630 | } |
||
631 | } |
||
632 | return result; |
||
633 | } |
||
634 | |||
635 | /** |
||
636 | * An implementation of `_.uniq` optimized for sorted arrays without support |
||
637 | * for callback shorthands and `this` binding. |
||
638 | * |
||
639 | * @private |
||
640 | * @param {Array} array The array to inspect. |
||
641 | * @param {Function} [iteratee] The function invoked per iteration. |
||
642 | * @returns {Array} Returns the new duplicate free array. |
||
643 | */ |
||
644 | function sortedUniq(array, iteratee) { |
||
645 | var seen, |
||
646 | index = -1, |
||
647 | length = array.length, |
||
648 | resIndex = -1, |
||
649 | result = []; |
||
650 | |||
651 | while (++index < length) { |
||
652 | var value = array[index], |
||
653 | computed = iteratee ? iteratee(value, index, array) : value; |
||
654 | |||
655 | if (!index || seen !== computed) { |
||
656 | seen = computed; |
||
657 | result[++resIndex] = value; |
||
658 | } |
||
659 | } |
||
660 | return result; |
||
661 | } |
||
662 | |||
663 | /** |
||
664 | * Used by `_.trim` and `_.trimLeft` to get the index of the first non-whitespace |
||
665 | * character of `string`. |
||
666 | * |
||
667 | * @private |
||
668 | * @param {string} string The string to inspect. |
||
669 | * @returns {number} Returns the index of the first non-whitespace character. |
||
670 | */ |
||
671 | function trimmedLeftIndex(string) { |
||
672 | var index = -1, |
||
673 | length = string.length; |
||
674 | |||
675 | while (++index < length && isSpace(string.charCodeAt(index))) {} |
||
676 | return index; |
||
677 | } |
||
678 | |||
679 | /** |
||
680 | * Used by `_.trim` and `_.trimRight` to get the index of the last non-whitespace |
||
681 | * character of `string`. |
||
682 | * |
||
683 | * @private |
||
684 | * @param {string} string The string to inspect. |
||
685 | * @returns {number} Returns the index of the last non-whitespace character. |
||
686 | */ |
||
687 | function trimmedRightIndex(string) { |
||
688 | var index = string.length; |
||
689 | |||
690 | while (index-- && isSpace(string.charCodeAt(index))) {} |
||
691 | return index; |
||
692 | } |
||
693 | |||
694 | /** |
||
695 | * Used by `_.unescape` to convert HTML entities to characters. |
||
696 | * |
||
697 | * @private |
||
698 | * @param {string} chr The matched character to unescape. |
||
699 | * @returns {string} Returns the unescaped character. |
||
700 | */ |
||
701 | function unescapeHtmlChar(chr) { |
||
702 | return htmlUnescapes[chr]; |
||
703 | } |
||
704 | |||
705 | /*--------------------------------------------------------------------------*/ |
||
706 | |||
707 | /** |
||
708 | * Create a new pristine `lodash` function using the given `context` object. |
||
709 | * |
||
710 | * @static |
||
711 | * @memberOf _ |
||
712 | * @category Utility |
||
713 | * @param {Object} [context=root] The context object. |
||
714 | * @returns {Function} Returns a new `lodash` function. |
||
715 | * @example |
||
716 | * |
||
717 | * _.mixin({ 'foo': _.constant('foo') }); |
||
718 | * |
||
719 | * var lodash = _.runInContext(); |
||
720 | * lodash.mixin({ 'bar': lodash.constant('bar') }); |
||
721 | * |
||
722 | * _.isFunction(_.foo); |
||
723 | * // => true |
||
724 | * _.isFunction(_.bar); |
||
725 | * // => false |
||
726 | * |
||
727 | * lodash.isFunction(lodash.foo); |
||
728 | * // => false |
||
729 | * lodash.isFunction(lodash.bar); |
||
730 | * // => true |
||
731 | * |
||
732 | * // using `context` to mock `Date#getTime` use in `_.now` |
||
733 | * var mock = _.runInContext({ |
||
734 | * 'Date': function() { |
||
735 | * return { 'getTime': getTimeMock }; |
||
736 | * } |
||
737 | * }); |
||
738 | * |
||
739 | * // or creating a suped-up `defer` in Node.js |
||
740 | * var defer = _.runInContext({ 'setTimeout': setImmediate }).defer; |
||
741 | */ |
||
742 | function runInContext(context) { |
||
743 | // Avoid issues with some ES3 environments that attempt to use values, named |
||
744 | // after built-in constructors like `Object`, for the creation of literals. |
||
745 | // ES5 clears this up by stating that literals must use built-in constructors. |
||
746 | // See https://es5.github.io/#x11.1.5 for more details. |
||
747 | context = context ? _.defaults(root.Object(), context, _.pick(root, contextProps)) : root; |
||
748 | |||
749 | /** Native constructor references. */ |
||
750 | var Array = context.Array, |
||
751 | Date = context.Date, |
||
752 | Error = context.Error, |
||
753 | Function = context.Function, |
||
754 | Math = context.Math, |
||
755 | Number = context.Number, |
||
756 | Object = context.Object, |
||
757 | RegExp = context.RegExp, |
||
758 | String = context.String, |
||
759 | TypeError = context.TypeError; |
||
760 | |||
761 | /** Used for native method references. */ |
||
762 | var arrayProto = Array.prototype, |
||
763 | errorProto = Error.prototype, |
||
764 | objectProto = Object.prototype, |
||
765 | stringProto = String.prototype; |
||
766 | |||
767 | /** Used to resolve the decompiled source of functions. */ |
||
768 | var fnToString = Function.prototype.toString; |
||
769 | |||
770 | /** Used to check objects for own properties. */ |
||
771 | var hasOwnProperty = objectProto.hasOwnProperty; |
||
772 | |||
773 | /** Used to generate unique IDs. */ |
||
774 | var idCounter = 0; |
||
775 | |||
776 | /** |
||
777 | * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring) |
||
778 | * of values. |
||
779 | */ |
||
780 | var objToString = objectProto.toString; |
||
781 | |||
782 | /** Used to restore the original `_` reference in `_.noConflict`. */ |
||
783 | var oldDash = root._; |
||
784 | |||
785 | /** Used to detect if a method is native. */ |
||
786 | var reIsNative = RegExp('^' + |
||
787 | fnToString.call(hasOwnProperty).replace(/[\\^$.*+?()[\]{}|]/g, '\\$&') |
||
788 | .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' |
||
789 | ); |
||
790 | |||
791 | /** Native method references. */ |
||
792 | var ArrayBuffer = context.ArrayBuffer, |
||
793 | clearTimeout = context.clearTimeout, |
||
794 | parseFloat = context.parseFloat, |
||
795 | pow = Math.pow, |
||
796 | propertyIsEnumerable = objectProto.propertyIsEnumerable, |
||
797 | Set = getNative(context, 'Set'), |
||
798 | setTimeout = context.setTimeout, |
||
799 | splice = arrayProto.splice, |
||
800 | Uint8Array = context.Uint8Array, |
||
801 | WeakMap = getNative(context, 'WeakMap'); |
||
802 | |||
803 | /* Native method references for those with the same name as other `lodash` methods. */ |
||
804 | var nativeCeil = Math.ceil, |
||
805 | nativeCreate = getNative(Object, 'create'), |
||
806 | nativeFloor = Math.floor, |
||
807 | nativeIsArray = getNative(Array, 'isArray'), |
||
808 | nativeIsFinite = context.isFinite, |
||
809 | nativeKeys = getNative(Object, 'keys'), |
||
810 | nativeMax = Math.max, |
||
811 | nativeMin = Math.min, |
||
812 | nativeNow = getNative(Date, 'now'), |
||
813 | nativeParseInt = context.parseInt, |
||
814 | nativeRandom = Math.random; |
||
815 | |||
816 | /** Used as references for `-Infinity` and `Infinity`. */ |
||
817 | var NEGATIVE_INFINITY = Number.NEGATIVE_INFINITY, |
||
818 | POSITIVE_INFINITY = Number.POSITIVE_INFINITY; |
||
819 | |||
820 | /** Used as references for the maximum length and index of an array. */ |
||
821 | var MAX_ARRAY_LENGTH = 4294967295, |
||
822 | MAX_ARRAY_INDEX = MAX_ARRAY_LENGTH - 1, |
||
823 | HALF_MAX_ARRAY_LENGTH = MAX_ARRAY_LENGTH >>> 1; |
||
824 | |||
825 | /** |
||
826 | * Used as the [maximum length](http://ecma-international.org/ecma-262/6.0/#sec-number.max_safe_integer) |
||
827 | * of an array-like value. |
||
828 | */ |
||
829 | var MAX_SAFE_INTEGER = 9007199254740991; |
||
830 | |||
831 | /** Used to store function metadata. */ |
||
832 | var metaMap = WeakMap && new WeakMap; |
||
833 | |||
834 | /** Used to lookup unminified function names. */ |
||
835 | var realNames = {}; |
||
836 | |||
837 | /** Used to lookup a type array constructors by `toStringTag`. */ |
||
838 | var ctorByTag = {}; |
||
839 | ctorByTag[float32Tag] = context.Float32Array; |
||
840 | ctorByTag[float64Tag] = context.Float64Array; |
||
841 | ctorByTag[int8Tag] = context.Int8Array; |
||
842 | ctorByTag[int16Tag] = context.Int16Array; |
||
843 | ctorByTag[int32Tag] = context.Int32Array; |
||
844 | ctorByTag[uint8Tag] = Uint8Array; |
||
845 | ctorByTag[uint8ClampedTag] = context.Uint8ClampedArray; |
||
846 | ctorByTag[uint16Tag] = context.Uint16Array; |
||
847 | ctorByTag[uint32Tag] = context.Uint32Array; |
||
848 | |||
849 | /** Used to avoid iterating over non-enumerable properties in IE < 9. */ |
||
850 | var nonEnumProps = {}; |
||
851 | nonEnumProps[arrayTag] = nonEnumProps[dateTag] = nonEnumProps[numberTag] = { 'constructor': true, 'toLocaleString': true, 'toString': true, 'valueOf': true }; |
||
852 | nonEnumProps[boolTag] = nonEnumProps[stringTag] = { 'constructor': true, 'toString': true, 'valueOf': true }; |
||
853 | nonEnumProps[errorTag] = nonEnumProps[funcTag] = nonEnumProps[regexpTag] = { 'constructor': true, 'toString': true }; |
||
854 | nonEnumProps[objectTag] = { 'constructor': true }; |
||
855 | |||
856 | arrayEach(shadowProps, function(key) { |
||
857 | for (var tag in nonEnumProps) { |
||
858 | if (hasOwnProperty.call(nonEnumProps, tag)) { |
||
859 | var props = nonEnumProps[tag]; |
||
860 | props[key] = hasOwnProperty.call(props, key); |
||
861 | } |
||
862 | } |
||
863 | }); |
||
864 | |||
865 | /*------------------------------------------------------------------------*/ |
||
866 | |||
867 | /** |
||
868 | * Creates a `lodash` object which wraps `value` to enable implicit chaining. |
||
869 | * Methods that operate on and return arrays, collections, and functions can |
||
870 | * be chained together. Methods that retrieve a single value or may return a |
||
871 | * primitive value will automatically end the chain returning the unwrapped |
||
872 | * value. Explicit chaining may be enabled using `_.chain`. The execution of |
||
873 | * chained methods is lazy, that is, execution is deferred until `_#value` |
||
874 | * is implicitly or explicitly called. |
||
875 | * |
||
876 | * Lazy evaluation allows several methods to support shortcut fusion. Shortcut |
||
877 | * fusion is an optimization strategy which merge iteratee calls; this can help |
||
878 | * to avoid the creation of intermediate data structures and greatly reduce the |
||
879 | * number of iteratee executions. |
||
880 | * |
||
881 | * Chaining is supported in custom builds as long as the `_#value` method is |
||
882 | * directly or indirectly included in the build. |
||
883 | * |
||
884 | * In addition to lodash methods, wrappers have `Array` and `String` methods. |
||
885 | * |
||
886 | * The wrapper `Array` methods are: |
||
887 | * `concat`, `join`, `pop`, `push`, `reverse`, `shift`, `slice`, `sort`, |
||
888 | * `splice`, and `unshift` |
||
889 | * |
||
890 | * The wrapper `String` methods are: |
||
891 | * `replace` and `split` |
||
892 | * |
||
893 | * The wrapper methods that support shortcut fusion are: |
||
894 | * `compact`, `drop`, `dropRight`, `dropRightWhile`, `dropWhile`, `filter`, |
||
895 | * `first`, `initial`, `last`, `map`, `pluck`, `reject`, `rest`, `reverse`, |
||
896 | * `slice`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, `toArray`, |
||
897 | * and `where` |
||
898 | * |
||
899 | * The chainable wrapper methods are: |
||
900 | * `after`, `ary`, `assign`, `at`, `before`, `bind`, `bindAll`, `bindKey`, |
||
901 | * `callback`, `chain`, `chunk`, `commit`, `compact`, `concat`, `constant`, |
||
902 | * `countBy`, `create`, `curry`, `debounce`, `defaults`, `defaultsDeep`, |
||
903 | * `defer`, `delay`, `difference`, `drop`, `dropRight`, `dropRightWhile`, |
||
904 | * `dropWhile`, `fill`, `filter`, `flatten`, `flattenDeep`, `flow`, `flowRight`, |
||
905 | * `forEach`, `forEachRight`, `forIn`, `forInRight`, `forOwn`, `forOwnRight`, |
||
906 | * `functions`, `groupBy`, `indexBy`, `initial`, `intersection`, `invert`, |
||
907 | * `invoke`, `keys`, `keysIn`, `map`, `mapKeys`, `mapValues`, `matches`, |
||
908 | * `matchesProperty`, `memoize`, `merge`, `method`, `methodOf`, `mixin`, |
||
909 | * `modArgs`, `negate`, `omit`, `once`, `pairs`, `partial`, `partialRight`, |
||
910 | * `partition`, `pick`, `plant`, `pluck`, `property`, `propertyOf`, `pull`, |
||
911 | * `pullAt`, `push`, `range`, `rearg`, `reject`, `remove`, `rest`, `restParam`, |
||
912 | * `reverse`, `set`, `shuffle`, `slice`, `sort`, `sortBy`, `sortByAll`, |
||
913 | * `sortByOrder`, `splice`, `spread`, `take`, `takeRight`, `takeRightWhile`, |
||
914 | * `takeWhile`, `tap`, `throttle`, `thru`, `times`, `toArray`, `toPlainObject`, |
||
915 | * `transform`, `union`, `uniq`, `unshift`, `unzip`, `unzipWith`, `values`, |
||
916 | * `valuesIn`, `where`, `without`, `wrap`, `xor`, `zip`, `zipObject`, `zipWith` |
||
917 | * |
||
918 | * The wrapper methods that are **not** chainable by default are: |
||
919 | * `add`, `attempt`, `camelCase`, `capitalize`, `ceil`, `clone`, `cloneDeep`, |
||
920 | * `deburr`, `endsWith`, `escape`, `escapeRegExp`, `every`, `find`, `findIndex`, |
||
921 | * `findKey`, `findLast`, `findLastIndex`, `findLastKey`, `findWhere`, `first`, |
||
922 | * `floor`, `get`, `gt`, `gte`, `has`, `identity`, `includes`, `indexOf`, |
||
923 | * `inRange`, `isArguments`, `isArray`, `isBoolean`, `isDate`, `isElement`, |
||
924 | * `isEmpty`, `isEqual`, `isError`, `isFinite` `isFunction`, `isMatch`, |
||
925 | * `isNative`, `isNaN`, `isNull`, `isNumber`, `isObject`, `isPlainObject`, |
||
926 | * `isRegExp`, `isString`, `isUndefined`, `isTypedArray`, `join`, `kebabCase`, |
||
927 | * `last`, `lastIndexOf`, `lt`, `lte`, `max`, `min`, `noConflict`, `noop`, |
||
928 | * `now`, `pad`, `padLeft`, `padRight`, `parseInt`, `pop`, `random`, `reduce`, |
||
929 | * `reduceRight`, `repeat`, `result`, `round`, `runInContext`, `shift`, `size`, |
||
930 | * `snakeCase`, `some`, `sortedIndex`, `sortedLastIndex`, `startCase`, |
||
931 | * `startsWith`, `sum`, `template`, `trim`, `trimLeft`, `trimRight`, `trunc`, |
||
932 | * `unescape`, `uniqueId`, `value`, and `words` |
||
933 | * |
||
934 | * The wrapper method `sample` will return a wrapped value when `n` is provided, |
||
935 | * otherwise an unwrapped value is returned. |
||
936 | * |
||
937 | * @name _ |
||
938 | * @constructor |
||
939 | * @category Chain |
||
940 | * @param {*} value The value to wrap in a `lodash` instance. |
||
941 | * @returns {Object} Returns the new `lodash` wrapper instance. |
||
942 | * @example |
||
943 | * |
||
944 | * var wrapped = _([1, 2, 3]); |
||
945 | * |
||
946 | * // returns an unwrapped value |
||
947 | * wrapped.reduce(function(total, n) { |
||
948 | * return total + n; |
||
949 | * }); |
||
950 | * // => 6 |
||
951 | * |
||
952 | * // returns a wrapped value |
||
953 | * var squares = wrapped.map(function(n) { |
||
954 | * return n * n; |
||
955 | * }); |
||
956 | * |
||
957 | * _.isArray(squares); |
||
958 | * // => false |
||
959 | * |
||
960 | * _.isArray(squares.value()); |
||
961 | * // => true |
||
962 | */ |
||
963 | function lodash(value) { |
||
964 | if (isObjectLike(value) && !isArray(value) && !(value instanceof LazyWrapper)) { |
||
965 | if (value instanceof LodashWrapper) { |
||
966 | return value; |
||
967 | } |
||
968 | if (hasOwnProperty.call(value, '__chain__') && hasOwnProperty.call(value, '__wrapped__')) { |
||
969 | return wrapperClone(value); |
||
970 | } |
||
971 | } |
||
972 | return new LodashWrapper(value); |
||
973 | } |
||
974 | |||
975 | /** |
||
976 | * The function whose prototype all chaining wrappers inherit from. |
||
977 | * |
||
978 | * @private |
||
979 | */ |
||
980 | function baseLodash() { |
||
981 | // No operation performed. |
||
982 | } |
||
983 | |||
984 | /** |
||
985 | * The base constructor for creating `lodash` wrapper objects. |
||
986 | * |
||
987 | * @private |
||
988 | * @param {*} value The value to wrap. |
||
989 | * @param {boolean} [chainAll] Enable chaining for all wrapper methods. |
||
990 | * @param {Array} [actions=[]] Actions to peform to resolve the unwrapped value. |
||
991 | */ |
||
992 | function LodashWrapper(value, chainAll, actions) { |
||
993 | this.__wrapped__ = value; |
||
994 | this.__actions__ = actions || []; |
||
995 | this.__chain__ = !!chainAll; |
||
996 | } |
||
997 | |||
998 | /** |
||
999 | * An object environment feature flags. |
||
1000 | * |
||
1001 | * @static |
||
1002 | * @memberOf _ |
||
1003 | * @type Object |
||
1004 | */ |
||
1005 | var support = lodash.support = {}; |
||
1006 | |||
1007 | (function(x) { |
||
1008 | var Ctor = function() { this.x = x; }, |
||
1009 | object = { '0': x, 'length': x }, |
||
1010 | props = []; |
||
1011 | |||
1012 | Ctor.prototype = { 'valueOf': x, 'y': x }; |
||
1013 | for (var key in new Ctor) { props.push(key); } |
||
1014 | |||
1015 | /** |
||
1016 | * Detect if `name` or `message` properties of `Error.prototype` are |
||
1017 | * enumerable by default (IE < 9, Safari < 5.1). |
||
1018 | * |
||
1019 | * @memberOf _.support |
||
1020 | * @type boolean |
||
1021 | */ |
||
1022 | support.enumErrorProps = propertyIsEnumerable.call(errorProto, 'message') || |
||
1023 | propertyIsEnumerable.call(errorProto, 'name'); |
||
1024 | |||
1025 | /** |
||
1026 | * Detect if `prototype` properties are enumerable by default. |
||
1027 | * |
||
1028 | * Firefox < 3.6, Opera > 9.50 - Opera < 11.60, and Safari < 5.1 |
||
1029 | * (if the prototype or a property on the prototype has been set) |
||
1030 | * incorrectly set the `[[Enumerable]]` value of a function's `prototype` |
||
1031 | * property to `true`. |
||
1032 | * |
||
1033 | * @memberOf _.support |
||
1034 | * @type boolean |
||
1035 | */ |
||
1036 | support.enumPrototypes = propertyIsEnumerable.call(Ctor, 'prototype'); |
||
1037 | |||
1038 | /** |
||
1039 | * Detect if properties shadowing those on `Object.prototype` are non-enumerable. |
||
1040 | * |
||
1041 | * In IE < 9 an object's own properties, shadowing non-enumerable ones, |
||
1042 | * are made non-enumerable as well (a.k.a the JScript `[[DontEnum]]` bug). |
||
1043 | * |
||
1044 | * @memberOf _.support |
||
1045 | * @type boolean |
||
1046 | */ |
||
1047 | support.nonEnumShadows = !/valueOf/.test(props); |
||
1048 | |||
1049 | /** |
||
1050 | * Detect if own properties are iterated after inherited properties (IE < 9). |
||
1051 | * |
||
1052 | * @memberOf _.support |
||
1053 | * @type boolean |
||
1054 | */ |
||
1055 | support.ownLast = props[0] != 'x'; |
||
1056 | |||
1057 | /** |
||
1058 | * Detect if `Array#shift` and `Array#splice` augment array-like objects |
||
1059 | * correctly. |
||
1060 | * |
||
1061 | * Firefox < 10, compatibility modes of IE 8, and IE < 9 have buggy Array |
||
1062 | * `shift()` and `splice()` functions that fail to remove the last element, |
||
1063 | * `value[0]`, of array-like objects even though the "length" property is |
||
1064 | * set to `0`. The `shift()` method is buggy in compatibility modes of IE 8, |
||
1065 | * while `splice()` is buggy regardless of mode in IE < 9. |
||
1066 | * |
||
1067 | * @memberOf _.support |
||
1068 | * @type boolean |
||
1069 | */ |
||
1070 | support.spliceObjects = (splice.call(object, 0, 1), !object[0]); |
||
1071 | |||
1072 | /** |
||
1073 | * Detect lack of support for accessing string characters by index. |
||
1074 | * |
||
1075 | * IE < 8 can't access characters by index. IE 8 can only access characters |
||
1076 | * by index on string literals, not string objects. |
||
1077 | * |
||
1078 | * @memberOf _.support |
||
1079 | * @type boolean |
||
1080 | */ |
||
1081 | support.unindexedChars = ('x'[0] + Object('x')[0]) != 'xx'; |
||
1082 | }(1, 0)); |
||
1083 | |||
1084 | /** |
||
1085 | * By default, the template delimiters used by lodash are like those in |
||
1086 | * embedded Ruby (ERB). Change the following template settings to use |
||
1087 | * alternative delimiters. |
||
1088 | * |
||
1089 | * @static |
||
1090 | * @memberOf _ |
||
1091 | * @type Object |
||
1092 | */ |
||
1093 | lodash.templateSettings = { |
||
1094 | |||
1095 | /** |
||
1096 | * Used to detect `data` property values to be HTML-escaped. |
||
1097 | * |
||
1098 | * @memberOf _.templateSettings |
||
1099 | * @type RegExp |
||
1100 | */ |
||
1101 | 'escape': reEscape, |
||
1102 | |||
1103 | /** |
||
1104 | * Used to detect code to be evaluated. |
||
1105 | * |
||
1106 | * @memberOf _.templateSettings |
||
1107 | * @type RegExp |
||
1108 | */ |
||
1109 | 'evaluate': reEvaluate, |
||
1110 | |||
1111 | /** |
||
1112 | * Used to detect `data` property values to inject. |
||
1113 | * |
||
1114 | * @memberOf _.templateSettings |
||
1115 | * @type RegExp |
||
1116 | */ |
||
1117 | 'interpolate': reInterpolate, |
||
1118 | |||
1119 | /** |
||
1120 | * Used to reference the data object in the template text. |
||
1121 | * |
||
1122 | * @memberOf _.templateSettings |
||
1123 | * @type string |
||
1124 | */ |
||
1125 | 'variable': '', |
||
1126 | |||
1127 | /** |
||
1128 | * Used to import variables into the compiled template. |
||
1129 | * |
||
1130 | * @memberOf _.templateSettings |
||
1131 | * @type Object |
||
1132 | */ |
||
1133 | 'imports': { |
||
1134 | |||
1135 | /** |
||
1136 | * A reference to the `lodash` function. |
||
1137 | * |
||
1138 | * @memberOf _.templateSettings.imports |
||
1139 | * @type Function |
||
1140 | */ |
||
1141 | '_': lodash |
||
1142 | } |
||
1143 | }; |
||
1144 | |||
1145 | /*------------------------------------------------------------------------*/ |
||
1146 | |||
1147 | /** |
||
1148 | * Creates a lazy wrapper object which wraps `value` to enable lazy evaluation. |
||
1149 | * |
||
1150 | * @private |
||
1151 | * @param {*} value The value to wrap. |
||
1152 | */ |
||
1153 | function LazyWrapper(value) { |
||
1154 | this.__wrapped__ = value; |
||
1155 | this.__actions__ = []; |
||
1156 | this.__dir__ = 1; |
||
1157 | this.__filtered__ = false; |
||
1158 | this.__iteratees__ = []; |
||
1159 | this.__takeCount__ = POSITIVE_INFINITY; |
||
1160 | this.__views__ = []; |
||
1161 | } |
||
1162 | |||
1163 | /** |
||
1164 | * Creates a clone of the lazy wrapper object. |
||
1165 | * |
||
1166 | * @private |
||
1167 | * @name clone |
||
1168 | * @memberOf LazyWrapper |
||
1169 | * @returns {Object} Returns the cloned `LazyWrapper` object. |
||
1170 | */ |
||
1171 | function lazyClone() { |
||
1172 | var result = new LazyWrapper(this.__wrapped__); |
||
1173 | result.__actions__ = arrayCopy(this.__actions__); |
||
1174 | result.__dir__ = this.__dir__; |
||
1175 | result.__filtered__ = this.__filtered__; |
||
1176 | result.__iteratees__ = arrayCopy(this.__iteratees__); |
||
1177 | result.__takeCount__ = this.__takeCount__; |
||
1178 | result.__views__ = arrayCopy(this.__views__); |
||
1179 | return result; |
||
1180 | } |
||
1181 | |||
1182 | /** |
||
1183 | * Reverses the direction of lazy iteration. |
||
1184 | * |
||
1185 | * @private |
||
1186 | * @name reverse |
||
1187 | * @memberOf LazyWrapper |
||
1188 | * @returns {Object} Returns the new reversed `LazyWrapper` object. |
||
1189 | */ |
||
1190 | function lazyReverse() { |
||
1191 | if (this.__filtered__) { |
||
1192 | var result = new LazyWrapper(this); |
||
1193 | result.__dir__ = -1; |
||
1194 | result.__filtered__ = true; |
||
1195 | } else { |
||
1196 | result = this.clone(); |
||
1197 | result.__dir__ *= -1; |
||
1198 | } |
||
1199 | return result; |
||
1200 | } |
||
1201 | |||
1202 | /** |
||
1203 | * Extracts the unwrapped value from its lazy wrapper. |
||
1204 | * |
||
1205 | * @private |
||
1206 | * @name value |
||
1207 | * @memberOf LazyWrapper |
||
1208 | * @returns {*} Returns the unwrapped value. |
||
1209 | */ |
||
1210 | function lazyValue() { |
||
1211 | var array = this.__wrapped__.value(), |
||
1212 | dir = this.__dir__, |
||
1213 | isArr = isArray(array), |
||
1214 | isRight = dir < 0, |
||
1215 | arrLength = isArr ? array.length : 0, |
||
1216 | view = getView(0, arrLength, this.__views__), |
||
1217 | start = view.start, |
||
1218 | end = view.end, |
||
1219 | length = end - start, |
||
1220 | index = isRight ? end : (start - 1), |
||
1221 | iteratees = this.__iteratees__, |
||
1222 | iterLength = iteratees.length, |
||
1223 | resIndex = 0, |
||
1224 | takeCount = nativeMin(length, this.__takeCount__); |
||
1225 | |||
1226 | if (!isArr || arrLength < LARGE_ARRAY_SIZE || (arrLength == length && takeCount == length)) { |
||
1227 | return baseWrapperValue(array, this.__actions__); |
||
1228 | } |
||
1229 | var result = []; |
||
1230 | |||
1231 | outer: |
||
1232 | while (length-- && resIndex < takeCount) { |
||
1233 | index += dir; |
||
1234 | |||
1235 | var iterIndex = -1, |
||
1236 | value = array[index]; |
||
1237 | |||
1238 | while (++iterIndex < iterLength) { |
||
1239 | var data = iteratees[iterIndex], |
||
1240 | iteratee = data.iteratee, |
||
1241 | type = data.type, |
||
1242 | computed = iteratee(value); |
||
1243 | |||
1244 | if (type == LAZY_MAP_FLAG) { |
||
1245 | value = computed; |
||
1246 | } else if (!computed) { |
||
1247 | if (type == LAZY_FILTER_FLAG) { |
||
1248 | continue outer; |
||
1249 | } else { |
||
1250 | break outer; |
||
1251 | } |
||
1252 | } |
||
1253 | } |
||
1254 | result[resIndex++] = value; |
||
1255 | } |
||
1256 | return result; |
||
1257 | } |
||
1258 | |||
1259 | /*------------------------------------------------------------------------*/ |
||
1260 | |||
1261 | /** |
||
1262 | * Creates a cache object to store key/value pairs. |
||
1263 | * |
||
1264 | * @private |
||
1265 | * @static |
||
1266 | * @name Cache |
||
1267 | * @memberOf _.memoize |
||
1268 | */ |
||
1269 | function MapCache() { |
||
1270 | this.__data__ = {}; |
||
1271 | } |
||
1272 | |||
1273 | /** |
||
1274 | * Removes `key` and its value from the cache. |
||
1275 | * |
||
1276 | * @private |
||
1277 | * @name delete |
||
1278 | * @memberOf _.memoize.Cache |
||
1279 | * @param {string} key The key of the value to remove. |
||
1280 | * @returns {boolean} Returns `true` if the entry was removed successfully, else `false`. |
||
1281 | */ |
||
1282 | function mapDelete(key) { |
||
1283 | return this.has(key) && delete this.__data__[key]; |
||
1284 | } |
||
1285 | |||
1286 | /** |
||
1287 | * Gets the cached value for `key`. |
||
1288 | * |
||
1289 | * @private |
||
1290 | * @name get |
||
1291 | * @memberOf _.memoize.Cache |
||
1292 | * @param {string} key The key of the value to get. |
||
1293 | * @returns {*} Returns the cached value. |
||
1294 | */ |
||
1295 | function mapGet(key) { |
||
1296 | return key == '__proto__' ? undefined : this.__data__[key]; |
||
1297 | } |
||
1298 | |||
1299 | /** |
||
1300 | * Checks if a cached value for `key` exists. |
||
1301 | * |
||
1302 | * @private |
||
1303 | * @name has |
||
1304 | * @memberOf _.memoize.Cache |
||
1305 | * @param {string} key The key of the entry to check. |
||
1306 | * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. |
||
1307 | */ |
||
1308 | function mapHas(key) { |
||
1309 | return key != '__proto__' && hasOwnProperty.call(this.__data__, key); |
||
1310 | } |
||
1311 | |||
1312 | /** |
||
1313 | * Sets `value` to `key` of the cache. |
||
1314 | * |
||
1315 | * @private |
||
1316 | * @name set |
||
1317 | * @memberOf _.memoize.Cache |
||
1318 | * @param {string} key The key of the value to cache. |
||
1319 | * @param {*} value The value to cache. |
||
1320 | * @returns {Object} Returns the cache object. |
||
1321 | */ |
||
1322 | function mapSet(key, value) { |
||
1323 | if (key != '__proto__') { |
||
1324 | this.__data__[key] = value; |
||
1325 | } |
||
1326 | return this; |
||
1327 | } |
||
1328 | |||
1329 | /*------------------------------------------------------------------------*/ |
||
1330 | |||
1331 | /** |
||
1332 | * |
||
1333 | * Creates a cache object to store unique values. |
||
1334 | * |
||
1335 | * @private |
||
1336 | * @param {Array} [values] The values to cache. |
||
1337 | */ |
||
1338 | function SetCache(values) { |
||
1339 | var length = values ? values.length : 0; |
||
1340 | |||
1341 | this.data = { 'hash': nativeCreate(null), 'set': new Set }; |
||
1342 | while (length--) { |
||
1343 | this.push(values[length]); |
||
1344 | } |
||
1345 | } |
||
1346 | |||
1347 | /** |
||
1348 | * Checks if `value` is in `cache` mimicking the return signature of |
||
1349 | * `_.indexOf` by returning `0` if the value is found, else `-1`. |
||
1350 | * |
||
1351 | * @private |
||
1352 | * @param {Object} cache The cache to search. |
||
1353 | * @param {*} value The value to search for. |
||
1354 | * @returns {number} Returns `0` if `value` is found, else `-1`. |
||
1355 | */ |
||
1356 | function cacheIndexOf(cache, value) { |
||
1357 | var data = cache.data, |
||
1358 | result = (typeof value == 'string' || isObject(value)) ? data.set.has(value) : data.hash[value]; |
||
1359 | |||
1360 | return result ? 0 : -1; |
||
1361 | } |
||
1362 | |||
1363 | /** |
||
1364 | * Adds `value` to the cache. |
||
1365 | * |
||
1366 | * @private |
||
1367 | * @name push |
||
1368 | * @memberOf SetCache |
||
1369 | * @param {*} value The value to cache. |
||
1370 | */ |
||
1371 | function cachePush(value) { |
||
1372 | var data = this.data; |
||
1373 | if (typeof value == 'string' || isObject(value)) { |
||
1374 | data.set.add(value); |
||
1375 | } else { |
||
1376 | data.hash[value] = true; |
||
1377 | } |
||
1378 | } |
||
1379 | |||
1380 | /*------------------------------------------------------------------------*/ |
||
1381 | |||
1382 | /** |
||
1383 | * Creates a new array joining `array` with `other`. |
||
1384 | * |
||
1385 | * @private |
||
1386 | * @param {Array} array The array to join. |
||
1387 | * @param {Array} other The other array to join. |
||
1388 | * @returns {Array} Returns the new concatenated array. |
||
1389 | */ |
||
1390 | function arrayConcat(array, other) { |
||
1391 | var index = -1, |
||
1392 | length = array.length, |
||
1393 | othIndex = -1, |
||
1394 | othLength = other.length, |
||
1395 | result = Array(length + othLength); |
||
1396 | |||
1397 | while (++index < length) { |
||
1398 | result[index] = array[index]; |
||
1399 | } |
||
1400 | while (++othIndex < othLength) { |
||
1401 | result[index++] = other[othIndex]; |
||
1402 | } |
||
1403 | return result; |
||
1404 | } |
||
1405 | |||
1406 | /** |
||
1407 | * Copies the values of `source` to `array`. |
||
1408 | * |
||
1409 | * @private |
||
1410 | * @param {Array} source The array to copy values from. |
||
1411 | * @param {Array} [array=[]] The array to copy values to. |
||
1412 | * @returns {Array} Returns `array`. |
||
1413 | */ |
||
1414 | function arrayCopy(source, array) { |
||
1415 | var index = -1, |
||
1416 | length = source.length; |
||
1417 | |||
1418 | array || (array = Array(length)); |
||
1419 | while (++index < length) { |
||
1420 | array[index] = source[index]; |
||
1421 | } |
||
1422 | return array; |
||
1423 | } |
||
1424 | |||
1425 | /** |
||
1426 | * A specialized version of `_.forEach` for arrays without support for callback |
||
1427 | * shorthands and `this` binding. |
||
1428 | * |
||
1429 | * @private |
||
1430 | * @param {Array} array The array to iterate over. |
||
1431 | * @param {Function} iteratee The function invoked per iteration. |
||
1432 | * @returns {Array} Returns `array`. |
||
1433 | */ |
||
1434 | function arrayEach(array, iteratee) { |
||
1435 | var index = -1, |
||
1436 | length = array.length; |
||
1437 | |||
1438 | while (++index < length) { |
||
1439 | if (iteratee(array[index], index, array) === false) { |
||
1440 | break; |
||
1441 | } |
||
1442 | } |
||
1443 | return array; |
||
1444 | } |
||
1445 | |||
1446 | /** |
||
1447 | * A specialized version of `_.forEachRight` for arrays without support for |
||
1448 | * callback shorthands and `this` binding. |
||
1449 | * |
||
1450 | * @private |
||
1451 | * @param {Array} array The array to iterate over. |
||
1452 | * @param {Function} iteratee The function invoked per iteration. |
||
1453 | * @returns {Array} Returns `array`. |
||
1454 | */ |
||
1455 | function arrayEachRight(array, iteratee) { |
||
1456 | var length = array.length; |
||
1457 | |||
1458 | while (length--) { |
||
1459 | if (iteratee(array[length], length, array) === false) { |
||
1460 | break; |
||
1461 | } |
||
1462 | } |
||
1463 | return array; |
||
1464 | } |
||
1465 | |||
1466 | /** |
||
1467 | * A specialized version of `_.every` for arrays without support for callback |
||
1468 | * shorthands and `this` binding. |
||
1469 | * |
||
1470 | * @private |
||
1471 | * @param {Array} array The array to iterate over. |
||
1472 | * @param {Function} predicate The function invoked per iteration. |
||
1473 | * @returns {boolean} Returns `true` if all elements pass the predicate check, |
||
1474 | * else `false`. |
||
1475 | */ |
||
1476 | function arrayEvery(array, predicate) { |
||
1477 | var index = -1, |
||
1478 | length = array.length; |
||
1479 | |||
1480 | while (++index < length) { |
||
1481 | if (!predicate(array[index], index, array)) { |
||
1482 | return false; |
||
1483 | } |
||
1484 | } |
||
1485 | return true; |
||
1486 | } |
||
1487 | |||
1488 | /** |
||
1489 | * A specialized version of `baseExtremum` for arrays which invokes `iteratee` |
||
1490 | * with one argument: (value). |
||
1491 | * |
||
1492 | * @private |
||
1493 | * @param {Array} array The array to iterate over. |
||
1494 | * @param {Function} iteratee The function invoked per iteration. |
||
1495 | * @param {Function} comparator The function used to compare values. |
||
1496 | * @param {*} exValue The initial extremum value. |
||
1497 | * @returns {*} Returns the extremum value. |
||
1498 | */ |
||
1499 | function arrayExtremum(array, iteratee, comparator, exValue) { |
||
1500 | var index = -1, |
||
1501 | length = array.length, |
||
1502 | computed = exValue, |
||
1503 | result = computed; |
||
1504 | |||
1505 | while (++index < length) { |
||
1506 | var value = array[index], |
||
1507 | current = +iteratee(value); |
||
1508 | |||
1509 | if (comparator(current, computed)) { |
||
1510 | computed = current; |
||
1511 | result = value; |
||
1512 | } |
||
1513 | } |
||
1514 | return result; |
||
1515 | } |
||
1516 | |||
1517 | /** |
||
1518 | * A specialized version of `_.filter` for arrays without support for callback |
||
1519 | * shorthands and `this` binding. |
||
1520 | * |
||
1521 | * @private |
||
1522 | * @param {Array} array The array to iterate over. |
||
1523 | * @param {Function} predicate The function invoked per iteration. |
||
1524 | * @returns {Array} Returns the new filtered array. |
||
1525 | */ |
||
1526 | function arrayFilter(array, predicate) { |
||
1527 | var index = -1, |
||
1528 | length = array.length, |
||
1529 | resIndex = -1, |
||
1530 | result = []; |
||
1531 | |||
1532 | while (++index < length) { |
||
1533 | var value = array[index]; |
||
1534 | if (predicate(value, index, array)) { |
||
1535 | result[++resIndex] = value; |
||
1536 | } |
||
1537 | } |
||
1538 | return result; |
||
1539 | } |
||
1540 | |||
1541 | /** |
||
1542 | * A specialized version of `_.map` for arrays without support for callback |
||
1543 | * shorthands and `this` binding. |
||
1544 | * |
||
1545 | * @private |
||
1546 | * @param {Array} array The array to iterate over. |
||
1547 | * @param {Function} iteratee The function invoked per iteration. |
||
1548 | * @returns {Array} Returns the new mapped array. |
||
1549 | */ |
||
1550 | function arrayMap(array, iteratee) { |
||
1551 | var index = -1, |
||
1552 | length = array.length, |
||
1553 | result = Array(length); |
||
1554 | |||
1555 | while (++index < length) { |
||
1556 | result[index] = iteratee(array[index], index, array); |
||
1557 | } |
||
1558 | return result; |
||
1559 | } |
||
1560 | |||
1561 | /** |
||
1562 | * Appends the elements of `values` to `array`. |
||
1563 | * |
||
1564 | * @private |
||
1565 | * @param {Array} array The array to modify. |
||
1566 | * @param {Array} values The values to append. |
||
1567 | * @returns {Array} Returns `array`. |
||
1568 | */ |
||
1569 | function arrayPush(array, values) { |
||
1570 | var index = -1, |
||
1571 | length = values.length, |
||
1572 | offset = array.length; |
||
1573 | |||
1574 | while (++index < length) { |
||
1575 | array[offset + index] = values[index]; |
||
1576 | } |
||
1577 | return array; |
||
1578 | } |
||
1579 | |||
1580 | /** |
||
1581 | * A specialized version of `_.reduce` for arrays without support for callback |
||
1582 | * shorthands and `this` binding. |
||
1583 | * |
||
1584 | * @private |
||
1585 | * @param {Array} array The array to iterate over. |
||
1586 | * @param {Function} iteratee The function invoked per iteration. |
||
1587 | * @param {*} [accumulator] The initial value. |
||
1588 | * @param {boolean} [initFromArray] Specify using the first element of `array` |
||
1589 | * as the initial value. |
||
1590 | * @returns {*} Returns the accumulated value. |
||
1591 | */ |
||
1592 | function arrayReduce(array, iteratee, accumulator, initFromArray) { |
||
1593 | var index = -1, |
||
1594 | length = array.length; |
||
1595 | |||
1596 | if (initFromArray && length) { |
||
1597 | accumulator = array[++index]; |
||
1598 | } |
||
1599 | while (++index < length) { |
||
1600 | accumulator = iteratee(accumulator, array[index], index, array); |
||
1601 | } |
||
1602 | return accumulator; |
||
1603 | } |
||
1604 | |||
1605 | /** |
||
1606 | * A specialized version of `_.reduceRight` for arrays without support for |
||
1607 | * callback shorthands and `this` binding. |
||
1608 | * |
||
1609 | * @private |
||
1610 | * @param {Array} array The array to iterate over. |
||
1611 | * @param {Function} iteratee The function invoked per iteration. |
||
1612 | * @param {*} [accumulator] The initial value. |
||
1613 | * @param {boolean} [initFromArray] Specify using the last element of `array` |
||
1614 | * as the initial value. |
||
1615 | * @returns {*} Returns the accumulated value. |
||
1616 | */ |
||
1617 | function arrayReduceRight(array, iteratee, accumulator, initFromArray) { |
||
1618 | var length = array.length; |
||
1619 | if (initFromArray && length) { |
||
1620 | accumulator = array[--length]; |
||
1621 | } |
||
1622 | while (length--) { |
||
1623 | accumulator = iteratee(accumulator, array[length], length, array); |
||
1624 | } |
||
1625 | return accumulator; |
||
1626 | } |
||
1627 | |||
1628 | /** |
||
1629 | * A specialized version of `_.some` for arrays without support for callback |
||
1630 | * shorthands and `this` binding. |
||
1631 | * |
||
1632 | * @private |
||
1633 | * @param {Array} array The array to iterate over. |
||
1634 | * @param {Function} predicate The function invoked per iteration. |
||
1635 | * @returns {boolean} Returns `true` if any element passes the predicate check, |
||
1636 | * else `false`. |
||
1637 | */ |
||
1638 | function arraySome(array, predicate) { |
||
1639 | var index = -1, |
||
1640 | length = array.length; |
||
1641 | |||
1642 | while (++index < length) { |
||
1643 | if (predicate(array[index], index, array)) { |
||
1644 | return true; |
||
1645 | } |
||
1646 | } |
||
1647 | return false; |
||
1648 | } |
||
1649 | |||
1650 | /** |
||
1651 | * A specialized version of `_.sum` for arrays without support for callback |
||
1652 | * shorthands and `this` binding.. |
||
1653 | * |
||
1654 | * @private |
||
1655 | * @param {Array} array The array to iterate over. |
||
1656 | * @param {Function} iteratee The function invoked per iteration. |
||
1657 | * @returns {number} Returns the sum. |
||
1658 | */ |
||
1659 | function arraySum(array, iteratee) { |
||
1660 | var length = array.length, |
||
1661 | result = 0; |
||
1662 | |||
1663 | while (length--) { |
||
1664 | result += +iteratee(array[length]) || 0; |
||
1665 | } |
||
1666 | return result; |
||
1667 | } |
||
1668 | |||
1669 | /** |
||
1670 | * Used by `_.defaults` to customize its `_.assign` use. |
||
1671 | * |
||
1672 | * @private |
||
1673 | * @param {*} objectValue The destination object property value. |
||
1674 | * @param {*} sourceValue The source object property value. |
||
1675 | * @returns {*} Returns the value to assign to the destination object. |
||
1676 | */ |
||
1677 | function assignDefaults(objectValue, sourceValue) { |
||
1678 | return objectValue === undefined ? sourceValue : objectValue; |
||
1679 | } |
||
1680 | |||
1681 | /** |
||
1682 | * Used by `_.template` to customize its `_.assign` use. |
||
1683 | * |
||
1684 | * **Note:** This function is like `assignDefaults` except that it ignores |
||
1685 | * inherited property values when checking if a property is `undefined`. |
||
1686 | * |
||
1687 | * @private |
||
1688 | * @param {*} objectValue The destination object property value. |
||
1689 | * @param {*} sourceValue The source object property value. |
||
1690 | * @param {string} key The key associated with the object and source values. |
||
1691 | * @param {Object} object The destination object. |
||
1692 | * @returns {*} Returns the value to assign to the destination object. |
||
1693 | */ |
||
1694 | function assignOwnDefaults(objectValue, sourceValue, key, object) { |
||
1695 | return (objectValue === undefined || !hasOwnProperty.call(object, key)) |
||
1696 | ? sourceValue |
||
1697 | : objectValue; |
||
1698 | } |
||
1699 | |||
1700 | /** |
||
1701 | * A specialized version of `_.assign` for customizing assigned values without |
||
1702 | * support for argument juggling, multiple sources, and `this` binding `customizer` |
||
1703 | * functions. |
||
1704 | * |
||
1705 | * @private |
||
1706 | * @param {Object} object The destination object. |
||
1707 | * @param {Object} source The source object. |
||
1708 | * @param {Function} customizer The function to customize assigned values. |
||
1709 | * @returns {Object} Returns `object`. |
||
1710 | */ |
||
1711 | function assignWith(object, source, customizer) { |
||
1712 | var index = -1, |
||
1713 | props = keys(source), |
||
1714 | length = props.length; |
||
1715 | |||
1716 | while (++index < length) { |
||
1717 | var key = props[index], |
||
1718 | value = object[key], |
||
1719 | result = customizer(value, source[key], key, object, source); |
||
1720 | |||
1721 | if ((result === result ? (result !== value) : (value === value)) || |
||
1722 | (value === undefined && !(key in object))) { |
||
1723 | object[key] = result; |
||
1724 | } |
||
1725 | } |
||
1726 | return object; |
||
1727 | } |
||
1728 | |||
1729 | /** |
||
1730 | * The base implementation of `_.assign` without support for argument juggling, |
||
1731 | * multiple sources, and `customizer` functions. |
||
1732 | * |
||
1733 | * @private |
||
1734 | * @param {Object} object The destination object. |
||
1735 | * @param {Object} source The source object. |
||
1736 | * @returns {Object} Returns `object`. |
||
1737 | */ |
||
1738 | function baseAssign(object, source) { |
||
1739 | return source == null |
||
1740 | ? object |
||
1741 | : baseCopy(source, keys(source), object); |
||
1742 | } |
||
1743 | |||
1744 | /** |
||
1745 | * The base implementation of `_.at` without support for string collections |
||
1746 | * and individual key arguments. |
||
1747 | * |
||
1748 | * @private |
||
1749 | * @param {Array|Object} collection The collection to iterate over. |
||
1750 | * @param {number[]|string[]} props The property names or indexes of elements to pick. |
||
1751 | * @returns {Array} Returns the new array of picked elements. |
||
1752 | */ |
||
1753 | function baseAt(collection, props) { |
||
1754 | var index = -1, |
||
1755 | isNil = collection == null, |
||
1756 | isArr = !isNil && isArrayLike(collection), |
||
1757 | length = isArr ? collection.length : 0, |
||
1758 | propsLength = props.length, |
||
1759 | result = Array(propsLength); |
||
1760 | |||
1761 | while(++index < propsLength) { |
||
1762 | var key = props[index]; |
||
1763 | if (isArr) { |
||
1764 | result[index] = isIndex(key, length) ? collection[key] : undefined; |
||
1765 | } else { |
||
1766 | result[index] = isNil ? undefined : collection[key]; |
||
1767 | } |
||
1768 | } |
||
1769 | return result; |
||
1770 | } |
||
1771 | |||
1772 | /** |
||
1773 | * Copies properties of `source` to `object`. |
||
1774 | * |
||
1775 | * @private |
||
1776 | * @param {Object} source The object to copy properties from. |
||
1777 | * @param {Array} props The property names to copy. |
||
1778 | * @param {Object} [object={}] The object to copy properties to. |
||
1779 | * @returns {Object} Returns `object`. |
||
1780 | */ |
||
1781 | function baseCopy(source, props, object) { |
||
1782 | object || (object = {}); |
||
1783 | |||
1784 | var index = -1, |
||
1785 | length = props.length; |
||
1786 | |||
1787 | while (++index < length) { |
||
1788 | var key = props[index]; |
||
1789 | object[key] = source[key]; |
||
1790 | } |
||
1791 | return object; |
||
1792 | } |
||
1793 | |||
1794 | /** |
||
1795 | * The base implementation of `_.callback` which supports specifying the |
||
1796 | * number of arguments to provide to `func`. |
||
1797 | * |
||
1798 | * @private |
||
1799 | * @param {*} [func=_.identity] The value to convert to a callback. |
||
1800 | * @param {*} [thisArg] The `this` binding of `func`. |
||
1801 | * @param {number} [argCount] The number of arguments to provide to `func`. |
||
1802 | * @returns {Function} Returns the callback. |
||
1803 | */ |
||
1804 | function baseCallback(func, thisArg, argCount) { |
||
1805 | var type = typeof func; |
||
1806 | if (type == 'function') { |
||
1807 | return thisArg === undefined |
||
1808 | ? func |
||
1809 | : bindCallback(func, thisArg, argCount); |
||
1810 | } |
||
1811 | if (func == null) { |
||
1812 | return identity; |
||
1813 | } |
||
1814 | if (type == 'object') { |
||
1815 | return baseMatches(func); |
||
1816 | } |
||
1817 | return thisArg === undefined |
||
1818 | ? property(func) |
||
1819 | : baseMatchesProperty(func, thisArg); |
||
1820 | } |
||
1821 | |||
1822 | /** |
||
1823 | * The base implementation of `_.clone` without support for argument juggling |
||
1824 | * and `this` binding `customizer` functions. |
||
1825 | * |
||
1826 | * @private |
||
1827 | * @param {*} value The value to clone. |
||
1828 | * @param {boolean} [isDeep] Specify a deep clone. |
||
1829 | * @param {Function} [customizer] The function to customize cloning values. |
||
1830 | * @param {string} [key] The key of `value`. |
||
1831 | * @param {Object} [object] The object `value` belongs to. |
||
1832 | * @param {Array} [stackA=[]] Tracks traversed source objects. |
||
1833 | * @param {Array} [stackB=[]] Associates clones with source counterparts. |
||
1834 | * @returns {*} Returns the cloned value. |
||
1835 | */ |
||
1836 | function baseClone(value, isDeep, customizer, key, object, stackA, stackB) { |
||
1837 | var result; |
||
1838 | if (customizer) { |
||
1839 | result = object ? customizer(value, key, object) : customizer(value); |
||
1840 | } |
||
1841 | if (result !== undefined) { |
||
1842 | return result; |
||
1843 | } |
||
1844 | if (!isObject(value)) { |
||
1845 | return value; |
||
1846 | } |
||
1847 | var isArr = isArray(value); |
||
1848 | if (isArr) { |
||
1849 | result = initCloneArray(value); |
||
1850 | if (!isDeep) { |
||
1851 | return arrayCopy(value, result); |
||
1852 | } |
||
1853 | } else { |
||
1854 | var tag = objToString.call(value), |
||
1855 | isFunc = tag == funcTag; |
||
1856 | |||
1857 | if (tag == objectTag || tag == argsTag || (isFunc && !object)) { |
||
1858 | if (isHostObject(value)) { |
||
1859 | return object ? value : {}; |
||
1860 | } |
||
1861 | result = initCloneObject(isFunc ? {} : value); |
||
1862 | if (!isDeep) { |
||
1863 | return baseAssign(result, value); |
||
1864 | } |
||
1865 | } else { |
||
1866 | return cloneableTags[tag] |
||
1867 | ? initCloneByTag(value, tag, isDeep) |
||
1868 | : (object ? value : {}); |
||
1869 | } |
||
1870 | } |
||
1871 | // Check for circular references and return its corresponding clone. |
||
1872 | stackA || (stackA = []); |
||
1873 | stackB || (stackB = []); |
||
1874 | |||
1875 | var length = stackA.length; |
||
1876 | while (length--) { |
||
1877 | if (stackA[length] == value) { |
||
1878 | return stackB[length]; |
||
1879 | } |
||
1880 | } |
||
1881 | // Add the source value to the stack of traversed objects and associate it with its clone. |
||
1882 | stackA.push(value); |
||
1883 | stackB.push(result); |
||
1884 | |||
1885 | // Recursively populate clone (susceptible to call stack limits). |
||
1886 | (isArr ? arrayEach : baseForOwn)(value, function(subValue, key) { |
||
1887 | result[key] = baseClone(subValue, isDeep, customizer, key, value, stackA, stackB); |
||
1888 | }); |
||
1889 | return result; |
||
1890 | } |
||
1891 | |||
1892 | /** |
||
1893 | * The base implementation of `_.create` without support for assigning |
||
1894 | * properties to the created object. |
||
1895 | * |
||
1896 | * @private |
||
1897 | * @param {Object} prototype The object to inherit from. |
||
1898 | * @returns {Object} Returns the new object. |
||
1899 | */ |
||
1900 | var baseCreate = (function() { |
||
1901 | function object() {} |
||
1902 | return function(prototype) { |
||
1903 | if (isObject(prototype)) { |
||
1904 | object.prototype = prototype; |
||
1905 | var result = new object; |
||
1906 | object.prototype = undefined; |
||
1907 | } |
||
1908 | return result || {}; |
||
1909 | }; |
||
1910 | }()); |
||
1911 | |||
1912 | /** |
||
1913 | * The base implementation of `_.delay` and `_.defer` which accepts an index |
||
1914 | * of where to slice the arguments to provide to `func`. |
||
1915 | * |
||
1916 | * @private |
||
1917 | * @param {Function} func The function to delay. |
||
1918 | * @param {number} wait The number of milliseconds to delay invocation. |
||
1919 | * @param {Object} args The arguments provide to `func`. |
||
1920 | * @returns {number} Returns the timer id. |
||
1921 | */ |
||
1922 | function baseDelay(func, wait, args) { |
||
1923 | if (typeof func != 'function') { |
||
1924 | throw new TypeError(FUNC_ERROR_TEXT); |
||
1925 | } |
||
1926 | return setTimeout(function() { func.apply(undefined, args); }, wait); |
||
1927 | } |
||
1928 | |||
1929 | /** |
||
1930 | * The base implementation of `_.difference` which accepts a single array |
||
1931 | * of values to exclude. |
||
1932 | * |
||
1933 | * @private |
||
1934 | * @param {Array} array The array to inspect. |
||
1935 | * @param {Array} values The values to exclude. |
||
1936 | * @returns {Array} Returns the new array of filtered values. |
||
1937 | */ |
||
1938 | function baseDifference(array, values) { |
||
1939 | var length = array ? array.length : 0, |
||
1940 | result = []; |
||
1941 | |||
1942 | if (!length) { |
||
1943 | return result; |
||
1944 | } |
||
1945 | var index = -1, |
||
1946 | indexOf = getIndexOf(), |
||
1947 | isCommon = indexOf === baseIndexOf, |
||
1948 | cache = (isCommon && values.length >= LARGE_ARRAY_SIZE) ? createCache(values) : null, |
||
1949 | valuesLength = values.length; |
||
1950 | |||
1951 | if (cache) { |
||
1952 | indexOf = cacheIndexOf; |
||
1953 | isCommon = false; |
||
1954 | values = cache; |
||
1955 | } |
||
1956 | outer: |
||
1957 | while (++index < length) { |
||
1958 | var value = array[index]; |
||
1959 | |||
1960 | if (isCommon && value === value) { |
||
1961 | var valuesIndex = valuesLength; |
||
1962 | while (valuesIndex--) { |
||
1963 | if (values[valuesIndex] === value) { |
||
1964 | continue outer; |
||
1965 | } |
||
1966 | } |
||
1967 | result.push(value); |
||
1968 | } |
||
1969 | else if (indexOf(values, value, 0) < 0) { |
||
1970 | result.push(value); |
||
1971 | } |
||
1972 | } |
||
1973 | return result; |
||
1974 | } |
||
1975 | |||
1976 | /** |
||
1977 | * The base implementation of `_.forEach` without support for callback |
||
1978 | * shorthands and `this` binding. |
||
1979 | * |
||
1980 | * @private |
||
1981 | * @param {Array|Object|string} collection The collection to iterate over. |
||
1982 | * @param {Function} iteratee The function invoked per iteration. |
||
1983 | * @returns {Array|Object|string} Returns `collection`. |
||
1984 | */ |
||
1985 | var baseEach = createBaseEach(baseForOwn); |
||
1986 | |||
1987 | /** |
||
1988 | * The base implementation of `_.forEachRight` without support for callback |
||
1989 | * shorthands and `this` binding. |
||
1990 | * |
||
1991 | * @private |
||
1992 | * @param {Array|Object|string} collection The collection to iterate over. |
||
1993 | * @param {Function} iteratee The function invoked per iteration. |
||
1994 | * @returns {Array|Object|string} Returns `collection`. |
||
1995 | */ |
||
1996 | var baseEachRight = createBaseEach(baseForOwnRight, true); |
||
1997 | |||
1998 | /** |
||
1999 | * The base implementation of `_.every` without support for callback |
||
2000 | * shorthands and `this` binding. |
||
2001 | * |
||
2002 | * @private |
||
2003 | * @param {Array|Object|string} collection The collection to iterate over. |
||
2004 | * @param {Function} predicate The function invoked per iteration. |
||
2005 | * @returns {boolean} Returns `true` if all elements pass the predicate check, |
||
2006 | * else `false` |
||
2007 | */ |
||
2008 | function baseEvery(collection, predicate) { |
||
2009 | var result = true; |
||
2010 | baseEach(collection, function(value, index, collection) { |
||
2011 | result = !!predicate(value, index, collection); |
||
2012 | return result; |
||
2013 | }); |
||
2014 | return result; |
||
2015 | } |
||
2016 | |||
2017 | /** |
||
2018 | * Gets the extremum value of `collection` invoking `iteratee` for each value |
||
2019 | * in `collection` to generate the criterion by which the value is ranked. |
||
2020 | * The `iteratee` is invoked with three arguments: (value, index|key, collection). |
||
2021 | * |
||
2022 | * @private |
||
2023 | * @param {Array|Object|string} collection The collection to iterate over. |
||
2024 | * @param {Function} iteratee The function invoked per iteration. |
||
2025 | * @param {Function} comparator The function used to compare values. |
||
2026 | * @param {*} exValue The initial extremum value. |
||
2027 | * @returns {*} Returns the extremum value. |
||
2028 | */ |
||
2029 | function baseExtremum(collection, iteratee, comparator, exValue) { |
||
2030 | var computed = exValue, |
||
2031 | result = computed; |
||
2032 | |||
2033 | baseEach(collection, function(value, index, collection) { |
||
2034 | var current = +iteratee(value, index, collection); |
||
2035 | if (comparator(current, computed) || (current === exValue && current === result)) { |
||
2036 | computed = current; |
||
2037 | result = value; |
||
2038 | } |
||
2039 | }); |
||
2040 | return result; |
||
2041 | } |
||
2042 | |||
2043 | /** |
||
2044 | * The base implementation of `_.fill` without an iteratee call guard. |
||
2045 | * |
||
2046 | * @private |
||
2047 | * @param {Array} array The array to fill. |
||
2048 | * @param {*} value The value to fill `array` with. |
||
2049 | * @param {number} [start=0] The start position. |
||
2050 | * @param {number} [end=array.length] The end position. |
||
2051 | * @returns {Array} Returns `array`. |
||
2052 | */ |
||
2053 | function baseFill(array, value, start, end) { |
||
2054 | var length = array.length; |
||
2055 | |||
2056 | start = start == null ? 0 : (+start || 0); |
||
2057 | if (start < 0) { |
||
2058 | start = -start > length ? 0 : (length + start); |
||
2059 | } |
||
2060 | end = (end === undefined || end > length) ? length : (+end || 0); |
||
2061 | if (end < 0) { |
||
2062 | end += length; |
||
2063 | } |
||
2064 | length = start > end ? 0 : (end >>> 0); |
||
2065 | start >>>= 0; |
||
2066 | |||
2067 | while (start < length) { |
||
2068 | array[start++] = value; |
||
2069 | } |
||
2070 | return array; |
||
2071 | } |
||
2072 | |||
2073 | /** |
||
2074 | * The base implementation of `_.filter` without support for callback |
||
2075 | * shorthands and `this` binding. |
||
2076 | * |
||
2077 | * @private |
||
2078 | * @param {Array|Object|string} collection The collection to iterate over. |
||
2079 | * @param {Function} predicate The function invoked per iteration. |
||
2080 | * @returns {Array} Returns the new filtered array. |
||
2081 | */ |
||
2082 | function baseFilter(collection, predicate) { |
||
2083 | var result = []; |
||
2084 | baseEach(collection, function(value, index, collection) { |
||
2085 | if (predicate(value, index, collection)) { |
||
2086 | result.push(value); |
||
2087 | } |
||
2088 | }); |
||
2089 | return result; |
||
2090 | } |
||
2091 | |||
2092 | /** |
||
2093 | * The base implementation of `_.find`, `_.findLast`, `_.findKey`, and `_.findLastKey`, |
||
2094 | * without support for callback shorthands and `this` binding, which iterates |
||
2095 | * over `collection` using the provided `eachFunc`. |
||
2096 | * |
||
2097 | * @private |
||
2098 | * @param {Array|Object|string} collection The collection to search. |
||
2099 | * @param {Function} predicate The function invoked per iteration. |
||
2100 | * @param {Function} eachFunc The function to iterate over `collection`. |
||
2101 | * @param {boolean} [retKey] Specify returning the key of the found element |
||
2102 | * instead of the element itself. |
||
2103 | * @returns {*} Returns the found element or its key, else `undefined`. |
||
2104 | */ |
||
2105 | function baseFind(collection, predicate, eachFunc, retKey) { |
||
2106 | var result; |
||
2107 | eachFunc(collection, function(value, key, collection) { |
||
2108 | if (predicate(value, key, collection)) { |
||
2109 | result = retKey ? key : value; |
||
2110 | return false; |
||
2111 | } |
||
2112 | }); |
||
2113 | return result; |
||
2114 | } |
||
2115 | |||
2116 | /** |
||
2117 | * The base implementation of `_.flatten` with added support for restricting |
||
2118 | * flattening and specifying the start index. |
||
2119 | * |
||
2120 | * @private |
||
2121 | * @param {Array} array The array to flatten. |
||
2122 | * @param {boolean} [isDeep] Specify a deep flatten. |
||
2123 | * @param {boolean} [isStrict] Restrict flattening to arrays-like objects. |
||
2124 | * @param {Array} [result=[]] The initial result value. |
||
2125 | * @returns {Array} Returns the new flattened array. |
||
2126 | */ |
||
2127 | function baseFlatten(array, isDeep, isStrict, result) { |
||
2128 | result || (result = []); |
||
2129 | |||
2130 | var index = -1, |
||
2131 | length = array.length; |
||
2132 | |||
2133 | while (++index < length) { |
||
2134 | var value = array[index]; |
||
2135 | if (isObjectLike(value) && isArrayLike(value) && |
||
2136 | (isStrict || isArray(value) || isArguments(value))) { |
||
2137 | if (isDeep) { |
||
2138 | // Recursively flatten arrays (susceptible to call stack limits). |
||
2139 | baseFlatten(value, isDeep, isStrict, result); |
||
2140 | } else { |
||
2141 | arrayPush(result, value); |
||
2142 | } |
||
2143 | } else if (!isStrict) { |
||
2144 | result[result.length] = value; |
||
2145 | } |
||
2146 | } |
||
2147 | return result; |
||
2148 | } |
||
2149 | |||
2150 | /** |
||
2151 | * The base implementation of `baseForIn` and `baseForOwn` which iterates |
||
2152 | * over `object` properties returned by `keysFunc` invoking `iteratee` for |
||
2153 | * each property. Iteratee functions may exit iteration early by explicitly |
||
2154 | * returning `false`. |
||
2155 | * |
||
2156 | * @private |
||
2157 | * @param {Object} object The object to iterate over. |
||
2158 | * @param {Function} iteratee The function invoked per iteration. |
||
2159 | * @param {Function} keysFunc The function to get the keys of `object`. |
||
2160 | * @returns {Object} Returns `object`. |
||
2161 | */ |
||
2162 | var baseFor = createBaseFor(); |
||
2163 | |||
2164 | /** |
||
2165 | * This function is like `baseFor` except that it iterates over properties |
||
2166 | * in the opposite order. |
||
2167 | * |
||
2168 | * @private |
||
2169 | * @param {Object} object The object to iterate over. |
||
2170 | * @param {Function} iteratee The function invoked per iteration. |
||
2171 | * @param {Function} keysFunc The function to get the keys of `object`. |
||
2172 | * @returns {Object} Returns `object`. |
||
2173 | */ |
||
2174 | var baseForRight = createBaseFor(true); |
||
2175 | |||
2176 | /** |
||
2177 | * The base implementation of `_.forIn` without support for callback |
||
2178 | * shorthands and `this` binding. |
||
2179 | * |
||
2180 | * @private |
||
2181 | * @param {Object} object The object to iterate over. |
||
2182 | * @param {Function} iteratee The function invoked per iteration. |
||
2183 | * @returns {Object} Returns `object`. |
||
2184 | */ |
||
2185 | function baseForIn(object, iteratee) { |
||
2186 | return baseFor(object, iteratee, keysIn); |
||
2187 | } |
||
2188 | |||
2189 | /** |
||
2190 | * The base implementation of `_.forOwn` without support for callback |
||
2191 | * shorthands and `this` binding. |
||
2192 | * |
||
2193 | * @private |
||
2194 | * @param {Object} object The object to iterate over. |
||
2195 | * @param {Function} iteratee The function invoked per iteration. |
||
2196 | * @returns {Object} Returns `object`. |
||
2197 | */ |
||
2198 | function baseForOwn(object, iteratee) { |
||
2199 | return baseFor(object, iteratee, keys); |
||
2200 | } |
||
2201 | |||
2202 | /** |
||
2203 | * The base implementation of `_.forOwnRight` without support for callback |
||
2204 | * shorthands and `this` binding. |
||
2205 | * |
||
2206 | * @private |
||
2207 | * @param {Object} object The object to iterate over. |
||
2208 | * @param {Function} iteratee The function invoked per iteration. |
||
2209 | * @returns {Object} Returns `object`. |
||
2210 | */ |
||
2211 | function baseForOwnRight(object, iteratee) { |
||
2212 | return baseForRight(object, iteratee, keys); |
||
2213 | } |
||
2214 | |||
2215 | /** |
||
2216 | * The base implementation of `_.functions` which creates an array of |
||
2217 | * `object` function property names filtered from those provided. |
||
2218 | * |
||
2219 | * @private |
||
2220 | * @param {Object} object The object to inspect. |
||
2221 | * @param {Array} props The property names to filter. |
||
2222 | * @returns {Array} Returns the new array of filtered property names. |
||
2223 | */ |
||
2224 | function baseFunctions(object, props) { |
||
2225 | var index = -1, |
||
2226 | length = props.length, |
||
2227 | resIndex = -1, |
||
2228 | result = []; |
||
2229 | |||
2230 | while (++index < length) { |
||
2231 | var key = props[index]; |
||
2232 | if (isFunction(object[key])) { |
||
2233 | result[++resIndex] = key; |
||
2234 | } |
||
2235 | } |
||
2236 | return result; |
||
2237 | } |
||
2238 | |||
2239 | /** |
||
2240 | * The base implementation of `get` without support for string paths |
||
2241 | * and default values. |
||
2242 | * |
||
2243 | * @private |
||
2244 | * @param {Object} object The object to query. |
||
2245 | * @param {Array} path The path of the property to get. |
||
2246 | * @param {string} [pathKey] The key representation of path. |
||
2247 | * @returns {*} Returns the resolved value. |
||
2248 | */ |
||
2249 | function baseGet(object, path, pathKey) { |
||
2250 | if (object == null) { |
||
2251 | return; |
||
2252 | } |
||
2253 | object = toObject(object); |
||
2254 | if (pathKey !== undefined && pathKey in object) { |
||
2255 | path = [pathKey]; |
||
2256 | } |
||
2257 | var index = 0, |
||
2258 | length = path.length; |
||
2259 | |||
2260 | while (object != null && index < length) { |
||
2261 | object = toObject(object)[path[index++]]; |
||
2262 | } |
||
2263 | return (index && index == length) ? object : undefined; |
||
2264 | } |
||
2265 | |||
2266 | /** |
||
2267 | * The base implementation of `_.isEqual` without support for `this` binding |
||
2268 | * `customizer` functions. |
||
2269 | * |
||
2270 | * @private |
||
2271 | * @param {*} value The value to compare. |
||
2272 | * @param {*} other The other value to compare. |
||
2273 | * @param {Function} [customizer] The function to customize comparing values. |
||
2274 | * @param {boolean} [isLoose] Specify performing partial comparisons. |
||
2275 | * @param {Array} [stackA] Tracks traversed `value` objects. |
||
2276 | * @param {Array} [stackB] Tracks traversed `other` objects. |
||
2277 | * @returns {boolean} Returns `true` if the values are equivalent, else `false`. |
||
2278 | */ |
||
2279 | function baseIsEqual(value, other, customizer, isLoose, stackA, stackB) { |
||
2280 | if (value === other) { |
||
2281 | return true; |
||
2282 | } |
||
2283 | if (value == null || other == null || (!isObject(value) && !isObjectLike(other))) { |
||
2284 | return value !== value && other !== other; |
||
2285 | } |
||
2286 | return baseIsEqualDeep(value, other, baseIsEqual, customizer, isLoose, stackA, stackB); |
||
2287 | } |
||
2288 | |||
2289 | /** |
||
2290 | * A specialized version of `baseIsEqual` for arrays and objects which performs |
||
2291 | * deep comparisons and tracks traversed objects enabling objects with circular |
||
2292 | * references to be compared. |
||
2293 | * |
||
2294 | * @private |
||
2295 | * @param {Object} object The object to compare. |
||
2296 | * @param {Object} other The other object to compare. |
||
2297 | * @param {Function} equalFunc The function to determine equivalents of values. |
||
2298 | * @param {Function} [customizer] The function to customize comparing objects. |
||
2299 | * @param {boolean} [isLoose] Specify performing partial comparisons. |
||
2300 | * @param {Array} [stackA=[]] Tracks traversed `value` objects. |
||
2301 | * @param {Array} [stackB=[]] Tracks traversed `other` objects. |
||
2302 | * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. |
||
2303 | */ |
||
2304 | function baseIsEqualDeep(object, other, equalFunc, customizer, isLoose, stackA, stackB) { |
||
2305 | var objIsArr = isArray(object), |
||
2306 | othIsArr = isArray(other), |
||
2307 | objTag = arrayTag, |
||
2308 | othTag = arrayTag; |
||
2309 | |||
2310 | if (!objIsArr) { |
||
2311 | objTag = objToString.call(object); |
||
2312 | if (objTag == argsTag) { |
||
2313 | objTag = objectTag; |
||
2314 | } else if (objTag != objectTag) { |
||
2315 | objIsArr = isTypedArray(object); |
||
2316 | } |
||
2317 | } |
||
2318 | if (!othIsArr) { |
||
2319 | othTag = objToString.call(other); |
||
2320 | if (othTag == argsTag) { |
||
2321 | othTag = objectTag; |
||
2322 | } else if (othTag != objectTag) { |
||
2323 | othIsArr = isTypedArray(other); |
||
2324 | } |
||
2325 | } |
||
2326 | var objIsObj = objTag == objectTag && !isHostObject(object), |
||
2327 | othIsObj = othTag == objectTag && !isHostObject(other), |
||
2328 | isSameTag = objTag == othTag; |
||
2329 | |||
2330 | if (isSameTag && !(objIsArr || objIsObj)) { |
||
2331 | return equalByTag(object, other, objTag); |
||
2332 | } |
||
2333 | if (!isLoose) { |
||
2334 | var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'), |
||
2335 | othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__'); |
||
2336 | |||
2337 | if (objIsWrapped || othIsWrapped) { |
||
2338 | return equalFunc(objIsWrapped ? object.value() : object, othIsWrapped ? other.value() : other, customizer, isLoose, stackA, stackB); |
||
2339 | } |
||
2340 | } |
||
2341 | if (!isSameTag) { |
||
2342 | return false; |
||
2343 | } |
||
2344 | // Assume cyclic values are equal. |
||
2345 | // For more information on detecting circular references see https://es5.github.io/#JO. |
||
2346 | stackA || (stackA = []); |
||
2347 | stackB || (stackB = []); |
||
2348 | |||
2349 | var length = stackA.length; |
||
2350 | while (length--) { |
||
2351 | if (stackA[length] == object) { |
||
2352 | return stackB[length] == other; |
||
2353 | } |
||
2354 | } |
||
2355 | // Add `object` and `other` to the stack of traversed objects. |
||
2356 | stackA.push(object); |
||
2357 | stackB.push(other); |
||
2358 | |||
2359 | var result = (objIsArr ? equalArrays : equalObjects)(object, other, equalFunc, customizer, isLoose, stackA, stackB); |
||
2360 | |||
2361 | stackA.pop(); |
||
2362 | stackB.pop(); |
||
2363 | |||
2364 | return result; |
||
2365 | } |
||
2366 | |||
2367 | /** |
||
2368 | * The base implementation of `_.isMatch` without support for callback |
||
2369 | * shorthands and `this` binding. |
||
2370 | * |
||
2371 | * @private |
||
2372 | * @param {Object} object The object to inspect. |
||
2373 | * @param {Array} matchData The propery names, values, and compare flags to match. |
||
2374 | * @param {Function} [customizer] The function to customize comparing objects. |
||
2375 | * @returns {boolean} Returns `true` if `object` is a match, else `false`. |
||
2376 | */ |
||
2377 | function baseIsMatch(object, matchData, customizer) { |
||
2378 | var index = matchData.length, |
||
2379 | length = index, |
||
2380 | noCustomizer = !customizer; |
||
2381 | |||
2382 | if (object == null) { |
||
2383 | return !length; |
||
2384 | } |
||
2385 | object = toObject(object); |
||
2386 | while (index--) { |
||
2387 | var data = matchData[index]; |
||
2388 | if ((noCustomizer && data[2]) |
||
2389 | ? data[1] !== object[data[0]] |
||
2390 | : !(data[0] in object) |
||
2391 | ) { |
||
2392 | return false; |
||
2393 | } |
||
2394 | } |
||
2395 | while (++index < length) { |
||
2396 | data = matchData[index]; |
||
2397 | var key = data[0], |
||
2398 | objValue = object[key], |
||
2399 | srcValue = data[1]; |
||
2400 | |||
2401 | if (noCustomizer && data[2]) { |
||
2402 | if (objValue === undefined && !(key in object)) { |
||
2403 | return false; |
||
2404 | } |
||
2405 | } else { |
||
2406 | var result = customizer ? customizer(objValue, srcValue, key) : undefined; |
||
2407 | if (!(result === undefined ? baseIsEqual(srcValue, objValue, customizer, true) : result)) { |
||
2408 | return false; |
||
2409 | } |
||
2410 | } |
||
2411 | } |
||
2412 | return true; |
||
2413 | } |
||
2414 | |||
2415 | /** |
||
2416 | * The base implementation of `_.map` without support for callback shorthands |
||
2417 | * and `this` binding. |
||
2418 | * |
||
2419 | * @private |
||
2420 | * @param {Array|Object|string} collection The collection to iterate over. |
||
2421 | * @param {Function} iteratee The function invoked per iteration. |
||
2422 | * @returns {Array} Returns the new mapped array. |
||
2423 | */ |
||
2424 | function baseMap(collection, iteratee) { |
||
2425 | var index = -1, |
||
2426 | result = isArrayLike(collection) ? Array(collection.length) : []; |
||
2427 | |||
2428 | baseEach(collection, function(value, key, collection) { |
||
2429 | result[++index] = iteratee(value, key, collection); |
||
2430 | }); |
||
2431 | return result; |
||
2432 | } |
||
2433 | |||
2434 | /** |
||
2435 | * The base implementation of `_.matches` which does not clone `source`. |
||
2436 | * |
||
2437 | * @private |
||
2438 | * @param {Object} source The object of property values to match. |
||
2439 | * @returns {Function} Returns the new function. |
||
2440 | */ |
||
2441 | function baseMatches(source) { |
||
2442 | var matchData = getMatchData(source); |
||
2443 | if (matchData.length == 1 && matchData[0][2]) { |
||
2444 | var key = matchData[0][0], |
||
2445 | value = matchData[0][1]; |
||
2446 | |||
2447 | return function(object) { |
||
2448 | if (object == null) { |
||
2449 | return false; |
||
2450 | } |
||
2451 | object = toObject(object); |
||
2452 | return object[key] === value && (value !== undefined || (key in object)); |
||
2453 | }; |
||
2454 | } |
||
2455 | return function(object) { |
||
2456 | return baseIsMatch(object, matchData); |
||
2457 | }; |
||
2458 | } |
||
2459 | |||
2460 | /** |
||
2461 | * The base implementation of `_.matchesProperty` which does not clone `srcValue`. |
||
2462 | * |
||
2463 | * @private |
||
2464 | * @param {string} path The path of the property to get. |
||
2465 | * @param {*} srcValue The value to compare. |
||
2466 | * @returns {Function} Returns the new function. |
||
2467 | */ |
||
2468 | function baseMatchesProperty(path, srcValue) { |
||
2469 | var isArr = isArray(path), |
||
2470 | isCommon = isKey(path) && isStrictComparable(srcValue), |
||
2471 | pathKey = (path + ''); |
||
2472 | |||
2473 | path = toPath(path); |
||
2474 | return function(object) { |
||
2475 | if (object == null) { |
||
2476 | return false; |
||
2477 | } |
||
2478 | var key = pathKey; |
||
2479 | object = toObject(object); |
||
2480 | if ((isArr || !isCommon) && !(key in object)) { |
||
2481 | object = path.length == 1 ? object : baseGet(object, baseSlice(path, 0, -1)); |
||
2482 | if (object == null) { |
||
2483 | return false; |
||
2484 | } |
||
2485 | key = last(path); |
||
2486 | object = toObject(object); |
||
2487 | } |
||
2488 | return object[key] === srcValue |
||
2489 | ? (srcValue !== undefined || (key in object)) |
||
2490 | : baseIsEqual(srcValue, object[key], undefined, true); |
||
2491 | }; |
||
2492 | } |
||
2493 | |||
2494 | /** |
||
2495 | * The base implementation of `_.merge` without support for argument juggling, |
||
2496 | * multiple sources, and `this` binding `customizer` functions. |
||
2497 | * |
||
2498 | * @private |
||
2499 | * @param {Object} object The destination object. |
||
2500 | * @param {Object} source The source object. |
||
2501 | * @param {Function} [customizer] The function to customize merged values. |
||
2502 | * @param {Array} [stackA=[]] Tracks traversed source objects. |
||
2503 | * @param {Array} [stackB=[]] Associates values with source counterparts. |
||
2504 | * @returns {Object} Returns `object`. |
||
2505 | */ |
||
2506 | function baseMerge(object, source, customizer, stackA, stackB) { |
||
2507 | if (!isObject(object)) { |
||
2508 | return object; |
||
2509 | } |
||
2510 | var isSrcArr = isArrayLike(source) && (isArray(source) || isTypedArray(source)), |
||
2511 | props = isSrcArr ? undefined : keys(source); |
||
2512 | |||
2513 | arrayEach(props || source, function(srcValue, key) { |
||
2514 | if (props) { |
||
2515 | key = srcValue; |
||
2516 | srcValue = source[key]; |
||
2517 | } |
||
2518 | if (isObjectLike(srcValue)) { |
||
2519 | stackA || (stackA = []); |
||
2520 | stackB || (stackB = []); |
||
2521 | baseMergeDeep(object, source, key, baseMerge, customizer, stackA, stackB); |
||
2522 | } |
||
2523 | else { |
||
2524 | var value = object[key], |
||
2525 | result = customizer ? customizer(value, srcValue, key, object, source) : undefined, |
||
2526 | isCommon = result === undefined; |
||
2527 | |||
2528 | if (isCommon) { |
||
2529 | result = srcValue; |
||
2530 | } |
||
2531 | if ((result !== undefined || (isSrcArr && !(key in object))) && |
||
2532 | (isCommon || (result === result ? (result !== value) : (value === value)))) { |
||
2533 | object[key] = result; |
||
2534 | } |
||
2535 | } |
||
2536 | }); |
||
2537 | return object; |
||
2538 | } |
||
2539 | |||
2540 | /** |
||
2541 | * A specialized version of `baseMerge` for arrays and objects which performs |
||
2542 | * deep merges and tracks traversed objects enabling objects with circular |
||
2543 | * references to be merged. |
||
2544 | * |
||
2545 | * @private |
||
2546 | * @param {Object} object The destination object. |
||
2547 | * @param {Object} source The source object. |
||
2548 | * @param {string} key The key of the value to merge. |
||
2549 | * @param {Function} mergeFunc The function to merge values. |
||
2550 | * @param {Function} [customizer] The function to customize merged values. |
||
2551 | * @param {Array} [stackA=[]] Tracks traversed source objects. |
||
2552 | * @param {Array} [stackB=[]] Associates values with source counterparts. |
||
2553 | * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. |
||
2554 | */ |
||
2555 | function baseMergeDeep(object, source, key, mergeFunc, customizer, stackA, stackB) { |
||
2556 | var length = stackA.length, |
||
2557 | srcValue = source[key]; |
||
2558 | |||
2559 | while (length--) { |
||
2560 | if (stackA[length] == srcValue) { |
||
2561 | object[key] = stackB[length]; |
||
2562 | return; |
||
2563 | } |
||
2564 | } |
||
2565 | var value = object[key], |
||
2566 | result = customizer ? customizer(value, srcValue, key, object, source) : undefined, |
||
2567 | isCommon = result === undefined; |
||
2568 | |||
2569 | if (isCommon) { |
||
2570 | result = srcValue; |
||
2571 | if (isArrayLike(srcValue) && (isArray(srcValue) || isTypedArray(srcValue))) { |
||
2572 | result = isArray(value) |
||
2573 | ? value |
||
2574 | : (isArrayLike(value) ? arrayCopy(value) : []); |
||
2575 | } |
||
2576 | else if (isPlainObject(srcValue) || isArguments(srcValue)) { |
||
2577 | result = isArguments(value) |
||
2578 | ? toPlainObject(value) |
||
2579 | : (isPlainObject(value) ? value : {}); |
||
2580 | } |
||
2581 | else { |
||
2582 | isCommon = false; |
||
2583 | } |
||
2584 | } |
||
2585 | // Add the source value to the stack of traversed objects and associate |
||
2586 | // it with its merged value. |
||
2587 | stackA.push(srcValue); |
||
2588 | stackB.push(result); |
||
2589 | |||
2590 | if (isCommon) { |
||
2591 | // Recursively merge objects and arrays (susceptible to call stack limits). |
||
2592 | object[key] = mergeFunc(result, srcValue, customizer, stackA, stackB); |
||
2593 | } else if (result === result ? (result !== value) : (value === value)) { |
||
2594 | object[key] = result; |
||
2595 | } |
||
2596 | } |
||
2597 | |||
2598 | /** |
||
2599 | * The base implementation of `_.property` without support for deep paths. |
||
2600 | * |
||
2601 | * @private |
||
2602 | * @param {string} key The key of the property to get. |
||
2603 | * @returns {Function} Returns the new function. |
||
2604 | */ |
||
2605 | function baseProperty(key) { |
||
2606 | return function(object) { |
||
2607 | return object == null ? undefined : toObject(object)[key]; |
||
2608 | }; |
||
2609 | } |
||
2610 | |||
2611 | /** |
||
2612 | * A specialized version of `baseProperty` which supports deep paths. |
||
2613 | * |
||
2614 | * @private |
||
2615 | * @param {Array|string} path The path of the property to get. |
||
2616 | * @returns {Function} Returns the new function. |
||
2617 | */ |
||
2618 | function basePropertyDeep(path) { |
||
2619 | var pathKey = (path + ''); |
||
2620 | path = toPath(path); |
||
2621 | return function(object) { |
||
2622 | return baseGet(object, path, pathKey); |
||
2623 | }; |
||
2624 | } |
||
2625 | |||
2626 | /** |
||
2627 | * The base implementation of `_.pullAt` without support for individual |
||
2628 | * index arguments and capturing the removed elements. |
||
2629 | * |
||
2630 | * @private |
||
2631 | * @param {Array} array The array to modify. |
||
2632 | * @param {number[]} indexes The indexes of elements to remove. |
||
2633 | * @returns {Array} Returns `array`. |
||
2634 | */ |
||
2635 | function basePullAt(array, indexes) { |
||
2636 | var length = array ? indexes.length : 0; |
||
2637 | while (length--) { |
||
2638 | var index = indexes[length]; |
||
2639 | if (index != previous && isIndex(index)) { |
||
2640 | var previous = index; |
||
2641 | splice.call(array, index, 1); |
||
2642 | } |
||
2643 | } |
||
2644 | return array; |
||
2645 | } |
||
2646 | |||
2647 | /** |
||
2648 | * The base implementation of `_.random` without support for argument juggling |
||
2649 | * and returning floating-point numbers. |
||
2650 | * |
||
2651 | * @private |
||
2652 | * @param {number} min The minimum possible value. |
||
2653 | * @param {number} max The maximum possible value. |
||
2654 | * @returns {number} Returns the random number. |
||
2655 | */ |
||
2656 | function baseRandom(min, max) { |
||
2657 | return min + nativeFloor(nativeRandom() * (max - min + 1)); |
||
2658 | } |
||
2659 | |||
2660 | /** |
||
2661 | * The base implementation of `_.reduce` and `_.reduceRight` without support |
||
2662 | * for callback shorthands and `this` binding, which iterates over `collection` |
||
2663 | * using the provided `eachFunc`. |
||
2664 | * |
||
2665 | * @private |
||
2666 | * @param {Array|Object|string} collection The collection to iterate over. |
||
2667 | * @param {Function} iteratee The function invoked per iteration. |
||
2668 | * @param {*} accumulator The initial value. |
||
2669 | * @param {boolean} initFromCollection Specify using the first or last element |
||
2670 | * of `collection` as the initial value. |
||
2671 | * @param {Function} eachFunc The function to iterate over `collection`. |
||
2672 | * @returns {*} Returns the accumulated value. |
||
2673 | */ |
||
2674 | function baseReduce(collection, iteratee, accumulator, initFromCollection, eachFunc) { |
||
2675 | eachFunc(collection, function(value, index, collection) { |
||
2676 | accumulator = initFromCollection |
||
2677 | ? (initFromCollection = false, value) |
||
2678 | : iteratee(accumulator, value, index, collection); |
||
2679 | }); |
||
2680 | return accumulator; |
||
2681 | } |
||
2682 | |||
2683 | /** |
||
2684 | * The base implementation of `setData` without support for hot loop detection. |
||
2685 | * |
||
2686 | * @private |
||
2687 | * @param {Function} func The function to associate metadata with. |
||
2688 | * @param {*} data The metadata. |
||
2689 | * @returns {Function} Returns `func`. |
||
2690 | */ |
||
2691 | var baseSetData = !metaMap ? identity : function(func, data) { |
||
2692 | metaMap.set(func, data); |
||
2693 | return func; |
||
2694 | }; |
||
2695 | |||
2696 | /** |
||
2697 | * The base implementation of `_.slice` without an iteratee call guard. |
||
2698 | * |
||
2699 | * @private |
||
2700 | * @param {Array} array The array to slice. |
||
2701 | * @param {number} [start=0] The start position. |
||
2702 | * @param {number} [end=array.length] The end position. |
||
2703 | * @returns {Array} Returns the slice of `array`. |
||
2704 | */ |
||
2705 | function baseSlice(array, start, end) { |
||
2706 | var index = -1, |
||
2707 | length = array.length; |
||
2708 | |||
2709 | start = start == null ? 0 : (+start || 0); |
||
2710 | if (start < 0) { |
||
2711 | start = -start > length ? 0 : (length + start); |
||
2712 | } |
||
2713 | end = (end === undefined || end > length) ? length : (+end || 0); |
||
2714 | if (end < 0) { |
||
2715 | end += length; |
||
2716 | } |
||
2717 | length = start > end ? 0 : ((end - start) >>> 0); |
||
2718 | start >>>= 0; |
||
2719 | |||
2720 | var result = Array(length); |
||
2721 | while (++index < length) { |
||
2722 | result[index] = array[index + start]; |
||
2723 | } |
||
2724 | return result; |
||
2725 | } |
||
2726 | |||
2727 | /** |
||
2728 | * The base implementation of `_.some` without support for callback shorthands |
||
2729 | * and `this` binding. |
||
2730 | * |
||
2731 | * @private |
||
2732 | * @param {Array|Object|string} collection The collection to iterate over. |
||
2733 | * @param {Function} predicate The function invoked per iteration. |
||
2734 | * @returns {boolean} Returns `true` if any element passes the predicate check, |
||
2735 | * else `false`. |
||
2736 | */ |
||
2737 | function baseSome(collection, predicate) { |
||
2738 | var result; |
||
2739 | |||
2740 | baseEach(collection, function(value, index, collection) { |
||
2741 | result = predicate(value, index, collection); |
||
2742 | return !result; |
||
2743 | }); |
||
2744 | return !!result; |
||
2745 | } |
||
2746 | |||
2747 | /** |
||
2748 | * The base implementation of `_.sortBy` which uses `comparer` to define |
||
2749 | * the sort order of `array` and replaces criteria objects with their |
||
2750 | * corresponding values. |
||
2751 | * |
||
2752 | * @private |
||
2753 | * @param {Array} array The array to sort. |
||
2754 | * @param {Function} comparer The function to define sort order. |
||
2755 | * @returns {Array} Returns `array`. |
||
2756 | */ |
||
2757 | function baseSortBy(array, comparer) { |
||
2758 | var length = array.length; |
||
2759 | |||
2760 | array.sort(comparer); |
||
2761 | while (length--) { |
||
2762 | array[length] = array[length].value; |
||
2763 | } |
||
2764 | return array; |
||
2765 | } |
||
2766 | |||
2767 | /** |
||
2768 | * The base implementation of `_.sortByOrder` without param guards. |
||
2769 | * |
||
2770 | * @private |
||
2771 | * @param {Array|Object|string} collection The collection to iterate over. |
||
2772 | * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by. |
||
2773 | * @param {boolean[]} orders The sort orders of `iteratees`. |
||
2774 | * @returns {Array} Returns the new sorted array. |
||
2775 | */ |
||
2776 | function baseSortByOrder(collection, iteratees, orders) { |
||
2777 | var callback = getCallback(), |
||
2778 | index = -1; |
||
2779 | |||
2780 | iteratees = arrayMap(iteratees, function(iteratee) { return callback(iteratee); }); |
||
2781 | |||
2782 | var result = baseMap(collection, function(value) { |
||
2783 | var criteria = arrayMap(iteratees, function(iteratee) { return iteratee(value); }); |
||
2784 | return { 'criteria': criteria, 'index': ++index, 'value': value }; |
||
2785 | }); |
||
2786 | |||
2787 | return baseSortBy(result, function(object, other) { |
||
2788 | return compareMultiple(object, other, orders); |
||
2789 | }); |
||
2790 | } |
||
2791 | |||
2792 | /** |
||
2793 | * The base implementation of `_.sum` without support for callback shorthands |
||
2794 | * and `this` binding. |
||
2795 | * |
||
2796 | * @private |
||
2797 | * @param {Array|Object|string} collection The collection to iterate over. |
||
2798 | * @param {Function} iteratee The function invoked per iteration. |
||
2799 | * @returns {number} Returns the sum. |
||
2800 | */ |
||
2801 | function baseSum(collection, iteratee) { |
||
2802 | var result = 0; |
||
2803 | baseEach(collection, function(value, index, collection) { |
||
2804 | result += +iteratee(value, index, collection) || 0; |
||
2805 | }); |
||
2806 | return result; |
||
2807 | } |
||
2808 | |||
2809 | /** |
||
2810 | * The base implementation of `_.uniq` without support for callback shorthands |
||
2811 | * and `this` binding. |
||
2812 | * |
||
2813 | * @private |
||
2814 | * @param {Array} array The array to inspect. |
||
2815 | * @param {Function} [iteratee] The function invoked per iteration. |
||
2816 | * @returns {Array} Returns the new duplicate free array. |
||
2817 | */ |
||
2818 | function baseUniq(array, iteratee) { |
||
2819 | var index = -1, |
||
2820 | indexOf = getIndexOf(), |
||
2821 | length = array.length, |
||
2822 | isCommon = indexOf === baseIndexOf, |
||
2823 | isLarge = isCommon && length >= LARGE_ARRAY_SIZE, |
||
2824 | seen = isLarge ? createCache() : null, |
||
2825 | result = []; |
||
2826 | |||
2827 | if (seen) { |
||
2828 | indexOf = cacheIndexOf; |
||
2829 | isCommon = false; |
||
2830 | } else { |
||
2831 | isLarge = false; |
||
2832 | seen = iteratee ? [] : result; |
||
2833 | } |
||
2834 | outer: |
||
2835 | while (++index < length) { |
||
2836 | var value = array[index], |
||
2837 | computed = iteratee ? iteratee(value, index, array) : value; |
||
2838 | |||
2839 | if (isCommon && value === value) { |
||
2840 | var seenIndex = seen.length; |
||
2841 | while (seenIndex--) { |
||
2842 | if (seen[seenIndex] === computed) { |
||
2843 | continue outer; |
||
2844 | } |
||
2845 | } |
||
2846 | if (iteratee) { |
||
2847 | seen.push(computed); |
||
2848 | } |
||
2849 | result.push(value); |
||
2850 | } |
||
2851 | else if (indexOf(seen, computed, 0) < 0) { |
||
2852 | if (iteratee || isLarge) { |
||
2853 | seen.push(computed); |
||
2854 | } |
||
2855 | result.push(value); |
||
2856 | } |
||
2857 | } |
||
2858 | return result; |
||
2859 | } |
||
2860 | |||
2861 | /** |
||
2862 | * The base implementation of `_.values` and `_.valuesIn` which creates an |
||
2863 | * array of `object` property values corresponding to the property names |
||
2864 | * of `props`. |
||
2865 | * |
||
2866 | * @private |
||
2867 | * @param {Object} object The object to query. |
||
2868 | * @param {Array} props The property names to get values for. |
||
2869 | * @returns {Object} Returns the array of property values. |
||
2870 | */ |
||
2871 | function baseValues(object, props) { |
||
2872 | var index = -1, |
||
2873 | length = props.length, |
||
2874 | result = Array(length); |
||
2875 | |||
2876 | while (++index < length) { |
||
2877 | result[index] = object[props[index]]; |
||
2878 | } |
||
2879 | return result; |
||
2880 | } |
||
2881 | |||
2882 | /** |
||
2883 | * The base implementation of `_.dropRightWhile`, `_.dropWhile`, `_.takeRightWhile`, |
||
2884 | * and `_.takeWhile` without support for callback shorthands and `this` binding. |
||
2885 | * |
||
2886 | * @private |
||
2887 | * @param {Array} array The array to query. |
||
2888 | * @param {Function} predicate The function invoked per iteration. |
||
2889 | * @param {boolean} [isDrop] Specify dropping elements instead of taking them. |
||
2890 | * @param {boolean} [fromRight] Specify iterating from right to left. |
||
2891 | * @returns {Array} Returns the slice of `array`. |
||
2892 | */ |
||
2893 | function baseWhile(array, predicate, isDrop, fromRight) { |
||
2894 | var length = array.length, |
||
2895 | index = fromRight ? length : -1; |
||
2896 | |||
2897 | while ((fromRight ? index-- : ++index < length) && predicate(array[index], index, array)) {} |
||
2898 | return isDrop |
||
2899 | ? baseSlice(array, (fromRight ? 0 : index), (fromRight ? index + 1 : length)) |
||
2900 | : baseSlice(array, (fromRight ? index + 1 : 0), (fromRight ? length : index)); |
||
2901 | } |
||
2902 | |||
2903 | /** |
||
2904 | * The base implementation of `wrapperValue` which returns the result of |
||
2905 | * performing a sequence of actions on the unwrapped `value`, where each |
||
2906 | * successive action is supplied the return value of the previous. |
||
2907 | * |
||
2908 | * @private |
||
2909 | * @param {*} value The unwrapped value. |
||
2910 | * @param {Array} actions Actions to peform to resolve the unwrapped value. |
||
2911 | * @returns {*} Returns the resolved value. |
||
2912 | */ |
||
2913 | function baseWrapperValue(value, actions) { |
||
2914 | var result = value; |
||
2915 | if (result instanceof LazyWrapper) { |
||
2916 | result = result.value(); |
||
2917 | } |
||
2918 | var index = -1, |
||
2919 | length = actions.length; |
||
2920 | |||
2921 | while (++index < length) { |
||
2922 | var action = actions[index]; |
||
2923 | result = action.func.apply(action.thisArg, arrayPush([result], action.args)); |
||
2924 | } |
||
2925 | return result; |
||
2926 | } |
||
2927 | |||
2928 | /** |
||
2929 | * Performs a binary search of `array` to determine the index at which `value` |
||
2930 | * should be inserted into `array` in order to maintain its sort order. |
||
2931 | * |
||
2932 | * @private |
||
2933 | * @param {Array} array The sorted array to inspect. |
||
2934 | * @param {*} value The value to evaluate. |
||
2935 | * @param {boolean} [retHighest] Specify returning the highest qualified index. |
||
2936 | * @returns {number} Returns the index at which `value` should be inserted |
||
2937 | * into `array`. |
||
2938 | */ |
||
2939 | function binaryIndex(array, value, retHighest) { |
||
2940 | var low = 0, |
||
2941 | high = array ? array.length : low; |
||
2942 | |||
2943 | if (typeof value == 'number' && value === value && high <= HALF_MAX_ARRAY_LENGTH) { |
||
2944 | while (low < high) { |
||
2945 | var mid = (low + high) >>> 1, |
||
2946 | computed = array[mid]; |
||
2947 | |||
2948 | if ((retHighest ? (computed <= value) : (computed < value)) && computed !== null) { |
||
2949 | low = mid + 1; |
||
2950 | } else { |
||
2951 | high = mid; |
||
2952 | } |
||
2953 | } |
||
2954 | return high; |
||
2955 | } |
||
2956 | return binaryIndexBy(array, value, identity, retHighest); |
||
2957 | } |
||
2958 | |||
2959 | /** |
||
2960 | * This function is like `binaryIndex` except that it invokes `iteratee` for |
||
2961 | * `value` and each element of `array` to compute their sort ranking. The |
||
2962 | * iteratee is invoked with one argument; (value). |
||
2963 | * |
||
2964 | * @private |
||
2965 | * @param {Array} array The sorted array to inspect. |
||
2966 | * @param {*} value The value to evaluate. |
||
2967 | * @param {Function} iteratee The function invoked per iteration. |
||
2968 | * @param {boolean} [retHighest] Specify returning the highest qualified index. |
||
2969 | * @returns {number} Returns the index at which `value` should be inserted |
||
2970 | * into `array`. |
||
2971 | */ |
||
2972 | function binaryIndexBy(array, value, iteratee, retHighest) { |
||
2973 | value = iteratee(value); |
||
2974 | |||
2975 | var low = 0, |
||
2976 | high = array ? array.length : 0, |
||
2977 | valIsNaN = value !== value, |
||
2978 | valIsNull = value === null, |
||
2979 | valIsUndef = value === undefined; |
||
2980 | |||
2981 | while (low < high) { |
||
2982 | var mid = nativeFloor((low + high) / 2), |
||
2983 | computed = iteratee(array[mid]), |
||
2984 | isDef = computed !== undefined, |
||
2985 | isReflexive = computed === computed; |
||
2986 | |||
2987 | View Code Duplication | if (valIsNaN) { |
|
2988 | var setLow = isReflexive || retHighest; |
||
2989 | } else if (valIsNull) { |
||
2990 | setLow = isReflexive && isDef && (retHighest || computed != null); |
||
2991 | } else if (valIsUndef) { |
||
2992 | setLow = isReflexive && (retHighest || isDef); |
||
2993 | } else if (computed == null) { |
||
2994 | setLow = false; |
||
2995 | } else { |
||
2996 | setLow = retHighest ? (computed <= value) : (computed < value); |
||
2997 | } |
||
2998 | if (setLow) { |
||
2999 | low = mid + 1; |
||
3000 | } else { |
||
3001 | high = mid; |
||
3002 | } |
||
3003 | } |
||
3004 | return nativeMin(high, MAX_ARRAY_INDEX); |
||
3005 | } |
||
3006 | |||
3007 | /** |
||
3008 | * A specialized version of `baseCallback` which only supports `this` binding |
||
3009 | * and specifying the number of arguments to provide to `func`. |
||
3010 | * |
||
3011 | * @private |
||
3012 | * @param {Function} func The function to bind. |
||
3013 | * @param {*} thisArg The `this` binding of `func`. |
||
3014 | * @param {number} [argCount] The number of arguments to provide to `func`. |
||
3015 | * @returns {Function} Returns the callback. |
||
3016 | */ |
||
3017 | function bindCallback(func, thisArg, argCount) { |
||
3018 | if (typeof func != 'function') { |
||
3019 | return identity; |
||
3020 | } |
||
3021 | if (thisArg === undefined) { |
||
3022 | return func; |
||
3023 | } |
||
3024 | switch (argCount) { |
||
3025 | case 1: return function(value) { |
||
3026 | return func.call(thisArg, value); |
||
3027 | }; |
||
3028 | case 3: return function(value, index, collection) { |
||
3029 | return func.call(thisArg, value, index, collection); |
||
3030 | }; |
||
3031 | case 4: return function(accumulator, value, index, collection) { |
||
3032 | return func.call(thisArg, accumulator, value, index, collection); |
||
3033 | }; |
||
3034 | case 5: return function(value, other, key, object, source) { |
||
3035 | return func.call(thisArg, value, other, key, object, source); |
||
3036 | }; |
||
3037 | } |
||
3038 | return function() { |
||
3039 | return func.apply(thisArg, arguments); |
||
3040 | }; |
||
3041 | } |
||
3042 | |||
3043 | /** |
||
3044 | * Creates a clone of the given array buffer. |
||
3045 | * |
||
3046 | * @private |
||
3047 | * @param {ArrayBuffer} buffer The array buffer to clone. |
||
3048 | * @returns {ArrayBuffer} Returns the cloned array buffer. |
||
3049 | */ |
||
3050 | function bufferClone(buffer) { |
||
3051 | var result = new ArrayBuffer(buffer.byteLength), |
||
3052 | view = new Uint8Array(result); |
||
3053 | |||
3054 | view.set(new Uint8Array(buffer)); |
||
3055 | return result; |
||
3056 | } |
||
3057 | |||
3058 | /** |
||
3059 | * Creates an array that is the composition of partially applied arguments, |
||
3060 | * placeholders, and provided arguments into a single array of arguments. |
||
3061 | * |
||
3062 | * @private |
||
3063 | * @param {Array|Object} args The provided arguments. |
||
3064 | * @param {Array} partials The arguments to prepend to those provided. |
||
3065 | * @param {Array} holders The `partials` placeholder indexes. |
||
3066 | * @returns {Array} Returns the new array of composed arguments. |
||
3067 | */ |
||
3068 | function composeArgs(args, partials, holders) { |
||
3069 | var holdersLength = holders.length, |
||
3070 | argsIndex = -1, |
||
3071 | argsLength = nativeMax(args.length - holdersLength, 0), |
||
3072 | leftIndex = -1, |
||
3073 | leftLength = partials.length, |
||
3074 | result = Array(leftLength + argsLength); |
||
3075 | |||
3076 | while (++leftIndex < leftLength) { |
||
3077 | result[leftIndex] = partials[leftIndex]; |
||
3078 | } |
||
3079 | while (++argsIndex < holdersLength) { |
||
3080 | result[holders[argsIndex]] = args[argsIndex]; |
||
3081 | } |
||
3082 | while (argsLength--) { |
||
3083 | result[leftIndex++] = args[argsIndex++]; |
||
3084 | } |
||
3085 | return result; |
||
3086 | } |
||
3087 | |||
3088 | /** |
||
3089 | * This function is like `composeArgs` except that the arguments composition |
||
3090 | * is tailored for `_.partialRight`. |
||
3091 | * |
||
3092 | * @private |
||
3093 | * @param {Array|Object} args The provided arguments. |
||
3094 | * @param {Array} partials The arguments to append to those provided. |
||
3095 | * @param {Array} holders The `partials` placeholder indexes. |
||
3096 | * @returns {Array} Returns the new array of composed arguments. |
||
3097 | */ |
||
3098 | function composeArgsRight(args, partials, holders) { |
||
3099 | var holdersIndex = -1, |
||
3100 | holdersLength = holders.length, |
||
3101 | argsIndex = -1, |
||
3102 | argsLength = nativeMax(args.length - holdersLength, 0), |
||
3103 | rightIndex = -1, |
||
3104 | rightLength = partials.length, |
||
3105 | result = Array(argsLength + rightLength); |
||
3106 | |||
3107 | while (++argsIndex < argsLength) { |
||
3108 | result[argsIndex] = args[argsIndex]; |
||
3109 | } |
||
3110 | var offset = argsIndex; |
||
3111 | while (++rightIndex < rightLength) { |
||
3112 | result[offset + rightIndex] = partials[rightIndex]; |
||
3113 | } |
||
3114 | while (++holdersIndex < holdersLength) { |
||
3115 | result[offset + holders[holdersIndex]] = args[argsIndex++]; |
||
3116 | } |
||
3117 | return result; |
||
3118 | } |
||
3119 | |||
3120 | /** |
||
3121 | * Creates a `_.countBy`, `_.groupBy`, `_.indexBy`, or `_.partition` function. |
||
3122 | * |
||
3123 | * @private |
||
3124 | * @param {Function} setter The function to set keys and values of the accumulator object. |
||
3125 | * @param {Function} [initializer] The function to initialize the accumulator object. |
||
3126 | * @returns {Function} Returns the new aggregator function. |
||
3127 | */ |
||
3128 | function createAggregator(setter, initializer) { |
||
3129 | return function(collection, iteratee, thisArg) { |
||
3130 | var result = initializer ? initializer() : {}; |
||
3131 | iteratee = getCallback(iteratee, thisArg, 3); |
||
3132 | |||
3133 | if (isArray(collection)) { |
||
3134 | var index = -1, |
||
3135 | length = collection.length; |
||
3136 | |||
3137 | while (++index < length) { |
||
3138 | var value = collection[index]; |
||
3139 | setter(result, value, iteratee(value, index, collection), collection); |
||
3140 | } |
||
3141 | } else { |
||
3142 | baseEach(collection, function(value, key, collection) { |
||
3143 | setter(result, value, iteratee(value, key, collection), collection); |
||
3144 | }); |
||
3145 | } |
||
3146 | return result; |
||
3147 | }; |
||
3148 | } |
||
3149 | |||
3150 | /** |
||
3151 | * Creates a `_.assign`, `_.defaults`, or `_.merge` function. |
||
3152 | * |
||
3153 | * @private |
||
3154 | * @param {Function} assigner The function to assign values. |
||
3155 | * @returns {Function} Returns the new assigner function. |
||
3156 | */ |
||
3157 | function createAssigner(assigner) { |
||
3158 | return restParam(function(object, sources) { |
||
3159 | var index = -1, |
||
3160 | length = object == null ? 0 : sources.length, |
||
3161 | customizer = length > 2 ? sources[length - 2] : undefined, |
||
3162 | guard = length > 2 ? sources[2] : undefined, |
||
3163 | thisArg = length > 1 ? sources[length - 1] : undefined; |
||
3164 | |||
3165 | if (typeof customizer == 'function') { |
||
3166 | customizer = bindCallback(customizer, thisArg, 5); |
||
3167 | length -= 2; |
||
3168 | } else { |
||
3169 | customizer = typeof thisArg == 'function' ? thisArg : undefined; |
||
3170 | length -= (customizer ? 1 : 0); |
||
3171 | } |
||
3172 | if (guard && isIterateeCall(sources[0], sources[1], guard)) { |
||
3173 | customizer = length < 3 ? undefined : customizer; |
||
3174 | length = 1; |
||
3175 | } |
||
3176 | while (++index < length) { |
||
3177 | var source = sources[index]; |
||
3178 | if (source) { |
||
3179 | assigner(object, source, customizer); |
||
3180 | } |
||
3181 | } |
||
3182 | return object; |
||
3183 | }); |
||
3184 | } |
||
3185 | |||
3186 | /** |
||
3187 | * Creates a `baseEach` or `baseEachRight` function. |
||
3188 | * |
||
3189 | * @private |
||
3190 | * @param {Function} eachFunc The function to iterate over a collection. |
||
3191 | * @param {boolean} [fromRight] Specify iterating from right to left. |
||
3192 | * @returns {Function} Returns the new base function. |
||
3193 | */ |
||
3194 | function createBaseEach(eachFunc, fromRight) { |
||
3195 | return function(collection, iteratee) { |
||
3196 | var length = collection ? getLength(collection) : 0; |
||
3197 | if (!isLength(length)) { |
||
3198 | return eachFunc(collection, iteratee); |
||
3199 | } |
||
3200 | var index = fromRight ? length : -1, |
||
3201 | iterable = toObject(collection); |
||
3202 | |||
3203 | while ((fromRight ? index-- : ++index < length)) { |
||
3204 | if (iteratee(iterable[index], index, iterable) === false) { |
||
3205 | break; |
||
3206 | } |
||
3207 | } |
||
3208 | return collection; |
||
3209 | }; |
||
3210 | } |
||
3211 | |||
3212 | /** |
||
3213 | * Creates a base function for `_.forIn` or `_.forInRight`. |
||
3214 | * |
||
3215 | * @private |
||
3216 | * @param {boolean} [fromRight] Specify iterating from right to left. |
||
3217 | * @returns {Function} Returns the new base function. |
||
3218 | */ |
||
3219 | function createBaseFor(fromRight) { |
||
3220 | return function(object, iteratee, keysFunc) { |
||
3221 | var iterable = toObject(object), |
||
3222 | props = keysFunc(object), |
||
3223 | length = props.length, |
||
3224 | index = fromRight ? length : -1; |
||
3225 | |||
3226 | while ((fromRight ? index-- : ++index < length)) { |
||
3227 | var key = props[index]; |
||
3228 | if (iteratee(iterable[key], key, iterable) === false) { |
||
3229 | break; |
||
3230 | } |
||
3231 | } |
||
3232 | return object; |
||
3233 | }; |
||
3234 | } |
||
3235 | |||
3236 | /** |
||
3237 | * Creates a function that wraps `func` and invokes it with the `this` |
||
3238 | * binding of `thisArg`. |
||
3239 | * |
||
3240 | * @private |
||
3241 | * @param {Function} func The function to bind. |
||
3242 | * @param {*} [thisArg] The `this` binding of `func`. |
||
3243 | * @returns {Function} Returns the new bound function. |
||
3244 | */ |
||
3245 | function createBindWrapper(func, thisArg) { |
||
3246 | var Ctor = createCtorWrapper(func); |
||
3247 | |||
3248 | function wrapper() { |
||
3249 | var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func; |
||
3250 | return fn.apply(thisArg, arguments); |
||
3251 | } |
||
3252 | return wrapper; |
||
3253 | } |
||
3254 | |||
3255 | /** |
||
3256 | * Creates a `Set` cache object to optimize linear searches of large arrays. |
||
3257 | * |
||
3258 | * @private |
||
3259 | * @param {Array} [values] The values to cache. |
||
3260 | * @returns {null|Object} Returns the new cache object if `Set` is supported, else `null`. |
||
3261 | */ |
||
3262 | function createCache(values) { |
||
3263 | return (nativeCreate && Set) ? new SetCache(values) : null; |
||
3264 | } |
||
3265 | |||
3266 | /** |
||
3267 | * Creates a function that produces compound words out of the words in a |
||
3268 | * given string. |
||
3269 | * |
||
3270 | * @private |
||
3271 | * @param {Function} callback The function to combine each word. |
||
3272 | * @returns {Function} Returns the new compounder function. |
||
3273 | */ |
||
3274 | function createCompounder(callback) { |
||
3275 | return function(string) { |
||
3276 | var index = -1, |
||
3277 | array = words(deburr(string)), |
||
3278 | length = array.length, |
||
3279 | result = ''; |
||
3280 | |||
3281 | while (++index < length) { |
||
3282 | result = callback(result, array[index], index); |
||
3283 | } |
||
3284 | return result; |
||
3285 | }; |
||
3286 | } |
||
3287 | |||
3288 | /** |
||
3289 | * Creates a function that produces an instance of `Ctor` regardless of |
||
3290 | * whether it was invoked as part of a `new` expression or by `call` or `apply`. |
||
3291 | * |
||
3292 | * @private |
||
3293 | * @param {Function} Ctor The constructor to wrap. |
||
3294 | * @returns {Function} Returns the new wrapped function. |
||
3295 | */ |
||
3296 | function createCtorWrapper(Ctor) { |
||
3297 | return function() { |
||
3298 | // Use a `switch` statement to work with class constructors. |
||
3299 | // See http://ecma-international.org/ecma-262/6.0/#sec-ecmascript-function-objects-call-thisargument-argumentslist |
||
3300 | // for more details. |
||
3301 | var args = arguments; |
||
3302 | switch (args.length) { |
||
3303 | case 0: return new Ctor; |
||
3304 | case 1: return new Ctor(args[0]); |
||
3305 | case 2: return new Ctor(args[0], args[1]); |
||
3306 | case 3: return new Ctor(args[0], args[1], args[2]); |
||
3307 | case 4: return new Ctor(args[0], args[1], args[2], args[3]); |
||
3308 | case 5: return new Ctor(args[0], args[1], args[2], args[3], args[4]); |
||
3309 | case 6: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5]); |
||
3310 | case 7: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5], args[6]); |
||
3311 | } |
||
3312 | var thisBinding = baseCreate(Ctor.prototype), |
||
3313 | result = Ctor.apply(thisBinding, args); |
||
3314 | |||
3315 | // Mimic the constructor's `return` behavior. |
||
3316 | // See https://es5.github.io/#x13.2.2 for more details. |
||
3317 | return isObject(result) ? result : thisBinding; |
||
3318 | }; |
||
3319 | } |
||
3320 | |||
3321 | /** |
||
3322 | * Creates a `_.curry` or `_.curryRight` function. |
||
3323 | * |
||
3324 | * @private |
||
3325 | * @param {boolean} flag The curry bit flag. |
||
3326 | * @returns {Function} Returns the new curry function. |
||
3327 | */ |
||
3328 | function createCurry(flag) { |
||
3329 | function curryFunc(func, arity, guard) { |
||
3330 | if (guard && isIterateeCall(func, arity, guard)) { |
||
3331 | arity = undefined; |
||
3332 | } |
||
3333 | var result = createWrapper(func, flag, undefined, undefined, undefined, undefined, undefined, arity); |
||
3334 | result.placeholder = curryFunc.placeholder; |
||
3335 | return result; |
||
3336 | } |
||
3337 | return curryFunc; |
||
3338 | } |
||
3339 | |||
3340 | /** |
||
3341 | * Creates a `_.defaults` or `_.defaultsDeep` function. |
||
3342 | * |
||
3343 | * @private |
||
3344 | * @param {Function} assigner The function to assign values. |
||
3345 | * @param {Function} customizer The function to customize assigned values. |
||
3346 | * @returns {Function} Returns the new defaults function. |
||
3347 | */ |
||
3348 | function createDefaults(assigner, customizer) { |
||
3349 | return restParam(function(args) { |
||
3350 | var object = args[0]; |
||
3351 | if (object == null) { |
||
3352 | return object; |
||
3353 | } |
||
3354 | args.push(customizer); |
||
3355 | return assigner.apply(undefined, args); |
||
3356 | }); |
||
3357 | } |
||
3358 | |||
3359 | /** |
||
3360 | * Creates a `_.max` or `_.min` function. |
||
3361 | * |
||
3362 | * @private |
||
3363 | * @param {Function} comparator The function used to compare values. |
||
3364 | * @param {*} exValue The initial extremum value. |
||
3365 | * @returns {Function} Returns the new extremum function. |
||
3366 | */ |
||
3367 | function createExtremum(comparator, exValue) { |
||
3368 | return function(collection, iteratee, thisArg) { |
||
3369 | if (thisArg && isIterateeCall(collection, iteratee, thisArg)) { |
||
3370 | iteratee = undefined; |
||
3371 | } |
||
3372 | iteratee = getCallback(iteratee, thisArg, 3); |
||
3373 | if (iteratee.length == 1) { |
||
3374 | collection = isArray(collection) ? collection : toIterable(collection); |
||
3375 | var result = arrayExtremum(collection, iteratee, comparator, exValue); |
||
3376 | if (!(collection.length && result === exValue)) { |
||
3377 | return result; |
||
3378 | } |
||
3379 | } |
||
3380 | return baseExtremum(collection, iteratee, comparator, exValue); |
||
3381 | }; |
||
3382 | } |
||
3383 | |||
3384 | /** |
||
3385 | * Creates a `_.find` or `_.findLast` function. |
||
3386 | * |
||
3387 | * @private |
||
3388 | * @param {Function} eachFunc The function to iterate over a collection. |
||
3389 | * @param {boolean} [fromRight] Specify iterating from right to left. |
||
3390 | * @returns {Function} Returns the new find function. |
||
3391 | */ |
||
3392 | function createFind(eachFunc, fromRight) { |
||
3393 | return function(collection, predicate, thisArg) { |
||
3394 | predicate = getCallback(predicate, thisArg, 3); |
||
3395 | if (isArray(collection)) { |
||
3396 | var index = baseFindIndex(collection, predicate, fromRight); |
||
3397 | return index > -1 ? collection[index] : undefined; |
||
3398 | } |
||
3399 | return baseFind(collection, predicate, eachFunc); |
||
3400 | }; |
||
3401 | } |
||
3402 | |||
3403 | /** |
||
3404 | * Creates a `_.findIndex` or `_.findLastIndex` function. |
||
3405 | * |
||
3406 | * @private |
||
3407 | * @param {boolean} [fromRight] Specify iterating from right to left. |
||
3408 | * @returns {Function} Returns the new find function. |
||
3409 | */ |
||
3410 | function createFindIndex(fromRight) { |
||
3411 | return function(array, predicate, thisArg) { |
||
3412 | if (!(array && array.length)) { |
||
3413 | return -1; |
||
3414 | } |
||
3415 | predicate = getCallback(predicate, thisArg, 3); |
||
3416 | return baseFindIndex(array, predicate, fromRight); |
||
3417 | }; |
||
3418 | } |
||
3419 | |||
3420 | /** |
||
3421 | * Creates a `_.findKey` or `_.findLastKey` function. |
||
3422 | * |
||
3423 | * @private |
||
3424 | * @param {Function} objectFunc The function to iterate over an object. |
||
3425 | * @returns {Function} Returns the new find function. |
||
3426 | */ |
||
3427 | function createFindKey(objectFunc) { |
||
3428 | return function(object, predicate, thisArg) { |
||
3429 | predicate = getCallback(predicate, thisArg, 3); |
||
3430 | return baseFind(object, predicate, objectFunc, true); |
||
3431 | }; |
||
3432 | } |
||
3433 | |||
3434 | /** |
||
3435 | * Creates a `_.flow` or `_.flowRight` function. |
||
3436 | * |
||
3437 | * @private |
||
3438 | * @param {boolean} [fromRight] Specify iterating from right to left. |
||
3439 | * @returns {Function} Returns the new flow function. |
||
3440 | */ |
||
3441 | function createFlow(fromRight) { |
||
3442 | return function() { |
||
3443 | var wrapper, |
||
3444 | length = arguments.length, |
||
3445 | index = fromRight ? length : -1, |
||
3446 | leftIndex = 0, |
||
3447 | funcs = Array(length); |
||
3448 | |||
3449 | while ((fromRight ? index-- : ++index < length)) { |
||
3450 | var func = funcs[leftIndex++] = arguments[index]; |
||
3451 | if (typeof func != 'function') { |
||
3452 | throw new TypeError(FUNC_ERROR_TEXT); |
||
3453 | } |
||
3454 | if (!wrapper && LodashWrapper.prototype.thru && getFuncName(func) == 'wrapper') { |
||
3455 | wrapper = new LodashWrapper([], true); |
||
3456 | } |
||
3457 | } |
||
3458 | index = wrapper ? -1 : length; |
||
3459 | while (++index < length) { |
||
3460 | func = funcs[index]; |
||
3461 | |||
3462 | var funcName = getFuncName(func), |
||
3463 | data = funcName == 'wrapper' ? getData(func) : undefined; |
||
3464 | |||
3465 | if (data && isLaziable(data[0]) && data[1] == (ARY_FLAG | CURRY_FLAG | PARTIAL_FLAG | REARG_FLAG) && !data[4].length && data[9] == 1) { |
||
3466 | wrapper = wrapper[getFuncName(data[0])].apply(wrapper, data[3]); |
||
3467 | } else { |
||
3468 | wrapper = (func.length == 1 && isLaziable(func)) ? wrapper[funcName]() : wrapper.thru(func); |
||
3469 | } |
||
3470 | } |
||
3471 | return function() { |
||
3472 | var args = arguments, |
||
3473 | value = args[0]; |
||
3474 | |||
3475 | if (wrapper && args.length == 1 && isArray(value) && value.length >= LARGE_ARRAY_SIZE) { |
||
3476 | return wrapper.plant(value).value(); |
||
3477 | } |
||
3478 | var index = 0, |
||
3479 | result = length ? funcs[index].apply(this, args) : value; |
||
3480 | |||
3481 | while (++index < length) { |
||
3482 | result = funcs[index].call(this, result); |
||
3483 | } |
||
3484 | return result; |
||
3485 | }; |
||
3486 | }; |
||
3487 | } |
||
3488 | |||
3489 | /** |
||
3490 | * Creates a function for `_.forEach` or `_.forEachRight`. |
||
3491 | * |
||
3492 | * @private |
||
3493 | * @param {Function} arrayFunc The function to iterate over an array. |
||
3494 | * @param {Function} eachFunc The function to iterate over a collection. |
||
3495 | * @returns {Function} Returns the new each function. |
||
3496 | */ |
||
3497 | function createForEach(arrayFunc, eachFunc) { |
||
3498 | return function(collection, iteratee, thisArg) { |
||
3499 | return (typeof iteratee == 'function' && thisArg === undefined && isArray(collection)) |
||
3500 | ? arrayFunc(collection, iteratee) |
||
3501 | : eachFunc(collection, bindCallback(iteratee, thisArg, 3)); |
||
3502 | }; |
||
3503 | } |
||
3504 | |||
3505 | /** |
||
3506 | * Creates a function for `_.forIn` or `_.forInRight`. |
||
3507 | * |
||
3508 | * @private |
||
3509 | * @param {Function} objectFunc The function to iterate over an object. |
||
3510 | * @returns {Function} Returns the new each function. |
||
3511 | */ |
||
3512 | function createForIn(objectFunc) { |
||
3513 | return function(object, iteratee, thisArg) { |
||
3514 | if (typeof iteratee != 'function' || thisArg !== undefined) { |
||
3515 | iteratee = bindCallback(iteratee, thisArg, 3); |
||
3516 | } |
||
3517 | return objectFunc(object, iteratee, keysIn); |
||
3518 | }; |
||
3519 | } |
||
3520 | |||
3521 | /** |
||
3522 | * Creates a function for `_.forOwn` or `_.forOwnRight`. |
||
3523 | * |
||
3524 | * @private |
||
3525 | * @param {Function} objectFunc The function to iterate over an object. |
||
3526 | * @returns {Function} Returns the new each function. |
||
3527 | */ |
||
3528 | function createForOwn(objectFunc) { |
||
3529 | return function(object, iteratee, thisArg) { |
||
3530 | if (typeof iteratee != 'function' || thisArg !== undefined) { |
||
3531 | iteratee = bindCallback(iteratee, thisArg, 3); |
||
3532 | } |
||
3533 | return objectFunc(object, iteratee); |
||
3534 | }; |
||
3535 | } |
||
3536 | |||
3537 | /** |
||
3538 | * Creates a function for `_.mapKeys` or `_.mapValues`. |
||
3539 | * |
||
3540 | * @private |
||
3541 | * @param {boolean} [isMapKeys] Specify mapping keys instead of values. |
||
3542 | * @returns {Function} Returns the new map function. |
||
3543 | */ |
||
3544 | function createObjectMapper(isMapKeys) { |
||
3545 | return function(object, iteratee, thisArg) { |
||
3546 | var result = {}; |
||
3547 | iteratee = getCallback(iteratee, thisArg, 3); |
||
3548 | |||
3549 | baseForOwn(object, function(value, key, object) { |
||
3550 | var mapped = iteratee(value, key, object); |
||
3551 | key = isMapKeys ? mapped : key; |
||
3552 | value = isMapKeys ? value : mapped; |
||
3553 | result[key] = value; |
||
3554 | }); |
||
3555 | return result; |
||
3556 | }; |
||
3557 | } |
||
3558 | |||
3559 | /** |
||
3560 | * Creates a function for `_.padLeft` or `_.padRight`. |
||
3561 | * |
||
3562 | * @private |
||
3563 | * @param {boolean} [fromRight] Specify padding from the right. |
||
3564 | * @returns {Function} Returns the new pad function. |
||
3565 | */ |
||
3566 | function createPadDir(fromRight) { |
||
3567 | return function(string, length, chars) { |
||
3568 | string = baseToString(string); |
||
3569 | return (fromRight ? string : '') + createPadding(string, length, chars) + (fromRight ? '' : string); |
||
3570 | }; |
||
3571 | } |
||
3572 | |||
3573 | /** |
||
3574 | * Creates a `_.partial` or `_.partialRight` function. |
||
3575 | * |
||
3576 | * @private |
||
3577 | * @param {boolean} flag The partial bit flag. |
||
3578 | * @returns {Function} Returns the new partial function. |
||
3579 | */ |
||
3580 | function createPartial(flag) { |
||
3581 | var partialFunc = restParam(function(func, partials) { |
||
3582 | var holders = replaceHolders(partials, partialFunc.placeholder); |
||
3583 | return createWrapper(func, flag, undefined, partials, holders); |
||
3584 | }); |
||
3585 | return partialFunc; |
||
3586 | } |
||
3587 | |||
3588 | /** |
||
3589 | * Creates a function for `_.reduce` or `_.reduceRight`. |
||
3590 | * |
||
3591 | * @private |
||
3592 | * @param {Function} arrayFunc The function to iterate over an array. |
||
3593 | * @param {Function} eachFunc The function to iterate over a collection. |
||
3594 | * @returns {Function} Returns the new each function. |
||
3595 | */ |
||
3596 | function createReduce(arrayFunc, eachFunc) { |
||
3597 | return function(collection, iteratee, accumulator, thisArg) { |
||
3598 | var initFromArray = arguments.length < 3; |
||
3599 | return (typeof iteratee == 'function' && thisArg === undefined && isArray(collection)) |
||
3600 | ? arrayFunc(collection, iteratee, accumulator, initFromArray) |
||
3601 | : baseReduce(collection, getCallback(iteratee, thisArg, 4), accumulator, initFromArray, eachFunc); |
||
3602 | }; |
||
3603 | } |
||
3604 | |||
3605 | /** |
||
3606 | * Creates a function that wraps `func` and invokes it with optional `this` |
||
3607 | * binding of, partial application, and currying. |
||
3608 | * |
||
3609 | * @private |
||
3610 | * @param {Function|string} func The function or method name to reference. |
||
3611 | * @param {number} bitmask The bitmask of flags. See `createWrapper` for more details. |
||
3612 | * @param {*} [thisArg] The `this` binding of `func`. |
||
3613 | * @param {Array} [partials] The arguments to prepend to those provided to the new function. |
||
3614 | * @param {Array} [holders] The `partials` placeholder indexes. |
||
3615 | * @param {Array} [partialsRight] The arguments to append to those provided to the new function. |
||
3616 | * @param {Array} [holdersRight] The `partialsRight` placeholder indexes. |
||
3617 | * @param {Array} [argPos] The argument positions of the new function. |
||
3618 | * @param {number} [ary] The arity cap of `func`. |
||
3619 | * @param {number} [arity] The arity of `func`. |
||
3620 | * @returns {Function} Returns the new wrapped function. |
||
3621 | */ |
||
3622 | function createHybridWrapper(func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity) { |
||
3623 | var isAry = bitmask & ARY_FLAG, |
||
3624 | isBind = bitmask & BIND_FLAG, |
||
3625 | isBindKey = bitmask & BIND_KEY_FLAG, |
||
3626 | isCurry = bitmask & CURRY_FLAG, |
||
3627 | isCurryBound = bitmask & CURRY_BOUND_FLAG, |
||
3628 | isCurryRight = bitmask & CURRY_RIGHT_FLAG, |
||
3629 | Ctor = isBindKey ? undefined : createCtorWrapper(func); |
||
3630 | |||
3631 | function wrapper() { |
||
3632 | // Avoid `arguments` object use disqualifying optimizations by |
||
3633 | // converting it to an array before providing it to other functions. |
||
3634 | var length = arguments.length, |
||
3635 | index = length, |
||
3636 | args = Array(length); |
||
3637 | |||
3638 | while (index--) { |
||
3639 | args[index] = arguments[index]; |
||
3640 | } |
||
3641 | if (partials) { |
||
3642 | args = composeArgs(args, partials, holders); |
||
3643 | } |
||
3644 | if (partialsRight) { |
||
3645 | args = composeArgsRight(args, partialsRight, holdersRight); |
||
3646 | } |
||
3647 | if (isCurry || isCurryRight) { |
||
3648 | var placeholder = wrapper.placeholder, |
||
3649 | argsHolders = replaceHolders(args, placeholder); |
||
3650 | |||
3651 | length -= argsHolders.length; |
||
3652 | if (length < arity) { |
||
3653 | var newArgPos = argPos ? arrayCopy(argPos) : undefined, |
||
3654 | newArity = nativeMax(arity - length, 0), |
||
3655 | newsHolders = isCurry ? argsHolders : undefined, |
||
3656 | newHoldersRight = isCurry ? undefined : argsHolders, |
||
3657 | newPartials = isCurry ? args : undefined, |
||
3658 | newPartialsRight = isCurry ? undefined : args; |
||
3659 | |||
3660 | bitmask |= (isCurry ? PARTIAL_FLAG : PARTIAL_RIGHT_FLAG); |
||
3661 | bitmask &= ~(isCurry ? PARTIAL_RIGHT_FLAG : PARTIAL_FLAG); |
||
3662 | |||
3663 | if (!isCurryBound) { |
||
3664 | bitmask &= ~(BIND_FLAG | BIND_KEY_FLAG); |
||
3665 | } |
||
3666 | var newData = [func, bitmask, thisArg, newPartials, newsHolders, newPartialsRight, newHoldersRight, newArgPos, ary, newArity], |
||
3667 | result = createHybridWrapper.apply(undefined, newData); |
||
3668 | |||
3669 | if (isLaziable(func)) { |
||
3670 | setData(result, newData); |
||
3671 | } |
||
3672 | result.placeholder = placeholder; |
||
3673 | return result; |
||
3674 | } |
||
3675 | } |
||
3676 | var thisBinding = isBind ? thisArg : this, |
||
3677 | fn = isBindKey ? thisBinding[func] : func; |
||
3678 | |||
3679 | if (argPos) { |
||
3680 | args = reorder(args, argPos); |
||
3681 | } |
||
3682 | if (isAry && ary < args.length) { |
||
3683 | args.length = ary; |
||
3684 | } |
||
3685 | if (this && this !== root && this instanceof wrapper) { |
||
3686 | fn = Ctor || createCtorWrapper(func); |
||
3687 | } |
||
3688 | return fn.apply(thisBinding, args); |
||
3689 | } |
||
3690 | return wrapper; |
||
3691 | } |
||
3692 | |||
3693 | /** |
||
3694 | * Creates the padding required for `string` based on the given `length`. |
||
3695 | * The `chars` string is truncated if the number of characters exceeds `length`. |
||
3696 | * |
||
3697 | * @private |
||
3698 | * @param {string} string The string to create padding for. |
||
3699 | * @param {number} [length=0] The padding length. |
||
3700 | * @param {string} [chars=' '] The string used as padding. |
||
3701 | * @returns {string} Returns the pad for `string`. |
||
3702 | */ |
||
3703 | function createPadding(string, length, chars) { |
||
3704 | var strLength = string.length; |
||
3705 | length = +length; |
||
3706 | |||
3707 | if (strLength >= length || !nativeIsFinite(length)) { |
||
3708 | return ''; |
||
3709 | } |
||
3710 | var padLength = length - strLength; |
||
3711 | chars = chars == null ? ' ' : (chars + ''); |
||
3712 | return repeat(chars, nativeCeil(padLength / chars.length)).slice(0, padLength); |
||
3713 | } |
||
3714 | |||
3715 | /** |
||
3716 | * Creates a function that wraps `func` and invokes it with the optional `this` |
||
3717 | * binding of `thisArg` and the `partials` prepended to those provided to |
||
3718 | * the wrapper. |
||
3719 | * |
||
3720 | * @private |
||
3721 | * @param {Function} func The function to partially apply arguments to. |
||
3722 | * @param {number} bitmask The bitmask of flags. See `createWrapper` for more details. |
||
3723 | * @param {*} thisArg The `this` binding of `func`. |
||
3724 | * @param {Array} partials The arguments to prepend to those provided to the new function. |
||
3725 | * @returns {Function} Returns the new bound function. |
||
3726 | */ |
||
3727 | function createPartialWrapper(func, bitmask, thisArg, partials) { |
||
3728 | var isBind = bitmask & BIND_FLAG, |
||
3729 | Ctor = createCtorWrapper(func); |
||
3730 | |||
3731 | function wrapper() { |
||
3732 | // Avoid `arguments` object use disqualifying optimizations by |
||
3733 | // converting it to an array before providing it `func`. |
||
3734 | var argsIndex = -1, |
||
3735 | argsLength = arguments.length, |
||
3736 | leftIndex = -1, |
||
3737 | leftLength = partials.length, |
||
3738 | args = Array(leftLength + argsLength); |
||
3739 | |||
3740 | while (++leftIndex < leftLength) { |
||
3741 | args[leftIndex] = partials[leftIndex]; |
||
3742 | } |
||
3743 | while (argsLength--) { |
||
3744 | args[leftIndex++] = arguments[++argsIndex]; |
||
3745 | } |
||
3746 | var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func; |
||
3747 | return fn.apply(isBind ? thisArg : this, args); |
||
3748 | } |
||
3749 | return wrapper; |
||
3750 | } |
||
3751 | |||
3752 | /** |
||
3753 | * Creates a `_.ceil`, `_.floor`, or `_.round` function. |
||
3754 | * |
||
3755 | * @private |
||
3756 | * @param {string} methodName The name of the `Math` method to use when rounding. |
||
3757 | * @returns {Function} Returns the new round function. |
||
3758 | */ |
||
3759 | function createRound(methodName) { |
||
3760 | var func = Math[methodName]; |
||
3761 | return function(number, precision) { |
||
3762 | precision = precision === undefined ? 0 : (+precision || 0); |
||
3763 | if (precision) { |
||
3764 | precision = pow(10, precision); |
||
3765 | return func(number * precision) / precision; |
||
3766 | } |
||
3767 | return func(number); |
||
3768 | }; |
||
3769 | } |
||
3770 | |||
3771 | /** |
||
3772 | * Creates a `_.sortedIndex` or `_.sortedLastIndex` function. |
||
3773 | * |
||
3774 | * @private |
||
3775 | * @param {boolean} [retHighest] Specify returning the highest qualified index. |
||
3776 | * @returns {Function} Returns the new index function. |
||
3777 | */ |
||
3778 | function createSortedIndex(retHighest) { |
||
3779 | return function(array, value, iteratee, thisArg) { |
||
3780 | var callback = getCallback(iteratee); |
||
3781 | return (iteratee == null && callback === baseCallback) |
||
3782 | ? binaryIndex(array, value, retHighest) |
||
3783 | : binaryIndexBy(array, value, callback(iteratee, thisArg, 1), retHighest); |
||
3784 | }; |
||
3785 | } |
||
3786 | |||
3787 | /** |
||
3788 | * Creates a function that either curries or invokes `func` with optional |
||
3789 | * `this` binding and partially applied arguments. |
||
3790 | * |
||
3791 | * @private |
||
3792 | * @param {Function|string} func The function or method name to reference. |
||
3793 | * @param {number} bitmask The bitmask of flags. |
||
3794 | * The bitmask may be composed of the following flags: |
||
3795 | * 1 - `_.bind` |
||
3796 | * 2 - `_.bindKey` |
||
3797 | * 4 - `_.curry` or `_.curryRight` of a bound function |
||
3798 | * 8 - `_.curry` |
||
3799 | * 16 - `_.curryRight` |
||
3800 | * 32 - `_.partial` |
||
3801 | * 64 - `_.partialRight` |
||
3802 | * 128 - `_.rearg` |
||
3803 | * 256 - `_.ary` |
||
3804 | * @param {*} [thisArg] The `this` binding of `func`. |
||
3805 | * @param {Array} [partials] The arguments to be partially applied. |
||
3806 | * @param {Array} [holders] The `partials` placeholder indexes. |
||
3807 | * @param {Array} [argPos] The argument positions of the new function. |
||
3808 | * @param {number} [ary] The arity cap of `func`. |
||
3809 | * @param {number} [arity] The arity of `func`. |
||
3810 | * @returns {Function} Returns the new wrapped function. |
||
3811 | */ |
||
3812 | function createWrapper(func, bitmask, thisArg, partials, holders, argPos, ary, arity) { |
||
3813 | var isBindKey = bitmask & BIND_KEY_FLAG; |
||
3814 | if (!isBindKey && typeof func != 'function') { |
||
3815 | throw new TypeError(FUNC_ERROR_TEXT); |
||
3816 | } |
||
3817 | var length = partials ? partials.length : 0; |
||
3818 | if (!length) { |
||
3819 | bitmask &= ~(PARTIAL_FLAG | PARTIAL_RIGHT_FLAG); |
||
3820 | partials = holders = undefined; |
||
3821 | } |
||
3822 | length -= (holders ? holders.length : 0); |
||
3823 | if (bitmask & PARTIAL_RIGHT_FLAG) { |
||
3824 | var partialsRight = partials, |
||
3825 | holdersRight = holders; |
||
3826 | |||
3827 | partials = holders = undefined; |
||
3828 | } |
||
3829 | var data = isBindKey ? undefined : getData(func), |
||
3830 | newData = [func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity]; |
||
3831 | |||
3832 | if (data) { |
||
3833 | mergeData(newData, data); |
||
3834 | bitmask = newData[1]; |
||
3835 | arity = newData[9]; |
||
3836 | } |
||
3837 | newData[9] = arity == null |
||
3838 | ? (isBindKey ? 0 : func.length) |
||
3839 | : (nativeMax(arity - length, 0) || 0); |
||
3840 | |||
3841 | if (bitmask == BIND_FLAG) { |
||
3842 | var result = createBindWrapper(newData[0], newData[2]); |
||
3843 | } else if ((bitmask == PARTIAL_FLAG || bitmask == (BIND_FLAG | PARTIAL_FLAG)) && !newData[4].length) { |
||
3844 | result = createPartialWrapper.apply(undefined, newData); |
||
3845 | } else { |
||
3846 | result = createHybridWrapper.apply(undefined, newData); |
||
3847 | } |
||
3848 | var setter = data ? baseSetData : setData; |
||
3849 | return setter(result, newData); |
||
3850 | } |
||
3851 | |||
3852 | /** |
||
3853 | * A specialized version of `baseIsEqualDeep` for arrays with support for |
||
3854 | * partial deep comparisons. |
||
3855 | * |
||
3856 | * @private |
||
3857 | * @param {Array} array The array to compare. |
||
3858 | * @param {Array} other The other array to compare. |
||
3859 | * @param {Function} equalFunc The function to determine equivalents of values. |
||
3860 | * @param {Function} [customizer] The function to customize comparing arrays. |
||
3861 | * @param {boolean} [isLoose] Specify performing partial comparisons. |
||
3862 | * @param {Array} [stackA] Tracks traversed `value` objects. |
||
3863 | * @param {Array} [stackB] Tracks traversed `other` objects. |
||
3864 | * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`. |
||
3865 | */ |
||
3866 | function equalArrays(array, other, equalFunc, customizer, isLoose, stackA, stackB) { |
||
3867 | var index = -1, |
||
3868 | arrLength = array.length, |
||
3869 | othLength = other.length; |
||
3870 | |||
3871 | if (arrLength != othLength && !(isLoose && othLength > arrLength)) { |
||
3872 | return false; |
||
3873 | } |
||
3874 | // Ignore non-index properties. |
||
3875 | while (++index < arrLength) { |
||
3876 | var arrValue = array[index], |
||
3877 | othValue = other[index], |
||
3878 | result = customizer ? customizer(isLoose ? othValue : arrValue, isLoose ? arrValue : othValue, index) : undefined; |
||
3879 | |||
3880 | if (result !== undefined) { |
||
3881 | if (result) { |
||
3882 | continue; |
||
3883 | } |
||
3884 | return false; |
||
3885 | } |
||
3886 | // Recursively compare arrays (susceptible to call stack limits). |
||
3887 | if (isLoose) { |
||
3888 | if (!arraySome(other, function(othValue) { |
||
3889 | return arrValue === othValue || equalFunc(arrValue, othValue, customizer, isLoose, stackA, stackB); |
||
3890 | })) { |
||
3891 | return false; |
||
3892 | } |
||
3893 | } else if (!(arrValue === othValue || equalFunc(arrValue, othValue, customizer, isLoose, stackA, stackB))) { |
||
3894 | return false; |
||
3895 | } |
||
3896 | } |
||
3897 | return true; |
||
3898 | } |
||
3899 | |||
3900 | /** |
||
3901 | * A specialized version of `baseIsEqualDeep` for comparing objects of |
||
3902 | * the same `toStringTag`. |
||
3903 | * |
||
3904 | * **Note:** This function only supports comparing values with tags of |
||
3905 | * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. |
||
3906 | * |
||
3907 | * @private |
||
3908 | * @param {Object} object The object to compare. |
||
3909 | * @param {Object} other The other object to compare. |
||
3910 | * @param {string} tag The `toStringTag` of the objects to compare. |
||
3911 | * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. |
||
3912 | */ |
||
3913 | function equalByTag(object, other, tag) { |
||
3914 | switch (tag) { |
||
3915 | case boolTag: |
||
3916 | case dateTag: |
||
3917 | // Coerce dates and booleans to numbers, dates to milliseconds and booleans |
||
3918 | // to `1` or `0` treating invalid dates coerced to `NaN` as not equal. |
||
3919 | return +object == +other; |
||
3920 | |||
3921 | case errorTag: |
||
3922 | return object.name == other.name && object.message == other.message; |
||
3923 | |||
3924 | case numberTag: |
||
3925 | // Treat `NaN` vs. `NaN` as equal. |
||
3926 | return (object != +object) |
||
3927 | ? other != +other |
||
3928 | : object == +other; |
||
3929 | |||
3930 | case regexpTag: |
||
3931 | case stringTag: |
||
3932 | // Coerce regexes to strings and treat strings primitives and string |
||
3933 | // objects as equal. See https://es5.github.io/#x15.10.6.4 for more details. |
||
3934 | return object == (other + ''); |
||
3935 | } |
||
3936 | return false; |
||
3937 | } |
||
3938 | |||
3939 | /** |
||
3940 | * A specialized version of `baseIsEqualDeep` for objects with support for |
||
3941 | * partial deep comparisons. |
||
3942 | * |
||
3943 | * @private |
||
3944 | * @param {Object} object The object to compare. |
||
3945 | * @param {Object} other The other object to compare. |
||
3946 | * @param {Function} equalFunc The function to determine equivalents of values. |
||
3947 | * @param {Function} [customizer] The function to customize comparing values. |
||
3948 | * @param {boolean} [isLoose] Specify performing partial comparisons. |
||
3949 | * @param {Array} [stackA] Tracks traversed `value` objects. |
||
3950 | * @param {Array} [stackB] Tracks traversed `other` objects. |
||
3951 | * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. |
||
3952 | */ |
||
3953 | function equalObjects(object, other, equalFunc, customizer, isLoose, stackA, stackB) { |
||
3954 | var objProps = keys(object), |
||
3955 | objLength = objProps.length, |
||
3956 | othProps = keys(other), |
||
3957 | othLength = othProps.length; |
||
3958 | |||
3959 | if (objLength != othLength && !isLoose) { |
||
3960 | return false; |
||
3961 | } |
||
3962 | var index = objLength; |
||
3963 | while (index--) { |
||
3964 | var key = objProps[index]; |
||
3965 | if (!(isLoose ? key in other : hasOwnProperty.call(other, key))) { |
||
3966 | return false; |
||
3967 | } |
||
3968 | } |
||
3969 | var skipCtor = isLoose; |
||
3970 | while (++index < objLength) { |
||
3971 | key = objProps[index]; |
||
3972 | var objValue = object[key], |
||
3973 | othValue = other[key], |
||
3974 | result = customizer ? customizer(isLoose ? othValue : objValue, isLoose? objValue : othValue, key) : undefined; |
||
3975 | |||
3976 | // Recursively compare objects (susceptible to call stack limits). |
||
3977 | if (!(result === undefined ? equalFunc(objValue, othValue, customizer, isLoose, stackA, stackB) : result)) { |
||
3978 | return false; |
||
3979 | } |
||
3980 | skipCtor || (skipCtor = key == 'constructor'); |
||
3981 | } |
||
3982 | if (!skipCtor) { |
||
3983 | var objCtor = object.constructor, |
||
3984 | othCtor = other.constructor; |
||
3985 | |||
3986 | // Non `Object` object instances with different constructors are not equal. |
||
3987 | View Code Duplication | if (objCtor != othCtor && |
|
3988 | ('constructor' in object && 'constructor' in other) && |
||
3989 | !(typeof objCtor == 'function' && objCtor instanceof objCtor && |
||
3990 | typeof othCtor == 'function' && othCtor instanceof othCtor)) { |
||
3991 | return false; |
||
3992 | } |
||
3993 | } |
||
3994 | return true; |
||
3995 | } |
||
3996 | |||
3997 | /** |
||
3998 | * Gets the appropriate "callback" function. If the `_.callback` method is |
||
3999 | * customized this function returns the custom method, otherwise it returns |
||
4000 | * the `baseCallback` function. If arguments are provided the chosen function |
||
4001 | * is invoked with them and its result is returned. |
||
4002 | * |
||
4003 | * @private |
||
4004 | * @returns {Function} Returns the chosen function or its result. |
||
4005 | */ |
||
4006 | function getCallback(func, thisArg, argCount) { |
||
4007 | var result = lodash.callback || callback; |
||
4008 | result = result === callback ? baseCallback : result; |
||
4009 | return argCount ? result(func, thisArg, argCount) : result; |
||
4010 | } |
||
4011 | |||
4012 | /** |
||
4013 | * Gets metadata for `func`. |
||
4014 | * |
||
4015 | * @private |
||
4016 | * @param {Function} func The function to query. |
||
4017 | * @returns {*} Returns the metadata for `func`. |
||
4018 | */ |
||
4019 | var getData = !metaMap ? noop : function(func) { |
||
4020 | return metaMap.get(func); |
||
4021 | }; |
||
4022 | |||
4023 | /** |
||
4024 | * Gets the name of `func`. |
||
4025 | * |
||
4026 | * @private |
||
4027 | * @param {Function} func The function to query. |
||
4028 | * @returns {string} Returns the function name. |
||
4029 | */ |
||
4030 | function getFuncName(func) { |
||
4031 | var result = (func.name + ''), |
||
4032 | array = realNames[result], |
||
4033 | length = array ? array.length : 0; |
||
4034 | |||
4035 | while (length--) { |
||
4036 | var data = array[length], |
||
4037 | otherFunc = data.func; |
||
4038 | if (otherFunc == null || otherFunc == func) { |
||
4039 | return data.name; |
||
4040 | } |
||
4041 | } |
||
4042 | return result; |
||
4043 | } |
||
4044 | |||
4045 | /** |
||
4046 | * Gets the appropriate "indexOf" function. If the `_.indexOf` method is |
||
4047 | * customized this function returns the custom method, otherwise it returns |
||
4048 | * the `baseIndexOf` function. If arguments are provided the chosen function |
||
4049 | * is invoked with them and its result is returned. |
||
4050 | * |
||
4051 | * @private |
||
4052 | * @returns {Function|number} Returns the chosen function or its result. |
||
4053 | */ |
||
4054 | function getIndexOf(collection, target, fromIndex) { |
||
4055 | var result = lodash.indexOf || indexOf; |
||
4056 | result = result === indexOf ? baseIndexOf : result; |
||
4057 | return collection ? result(collection, target, fromIndex) : result; |
||
4058 | } |
||
4059 | |||
4060 | /** |
||
4061 | * Gets the "length" property value of `object`. |
||
4062 | * |
||
4063 | * **Note:** This function is used to avoid a [JIT bug](https://bugs.webkit.org/show_bug.cgi?id=142792) |
||
4064 | * that affects Safari on at least iOS 8.1-8.3 ARM64. |
||
4065 | * |
||
4066 | * @private |
||
4067 | * @param {Object} object The object to query. |
||
4068 | * @returns {*} Returns the "length" value. |
||
4069 | */ |
||
4070 | var getLength = baseProperty('length'); |
||
4071 | |||
4072 | /** |
||
4073 | * Gets the propery names, values, and compare flags of `object`. |
||
4074 | * |
||
4075 | * @private |
||
4076 | * @param {Object} object The object to query. |
||
4077 | * @returns {Array} Returns the match data of `object`. |
||
4078 | */ |
||
4079 | function getMatchData(object) { |
||
4080 | var result = pairs(object), |
||
4081 | length = result.length; |
||
4082 | |||
4083 | while (length--) { |
||
4084 | result[length][2] = isStrictComparable(result[length][1]); |
||
4085 | } |
||
4086 | return result; |
||
4087 | } |
||
4088 | |||
4089 | /** |
||
4090 | * Gets the native function at `key` of `object`. |
||
4091 | * |
||
4092 | * @private |
||
4093 | * @param {Object} object The object to query. |
||
4094 | * @param {string} key The key of the method to get. |
||
4095 | * @returns {*} Returns the function if it's native, else `undefined`. |
||
4096 | */ |
||
4097 | function getNative(object, key) { |
||
4098 | var value = object == null ? undefined : object[key]; |
||
4099 | return isNative(value) ? value : undefined; |
||
4100 | } |
||
4101 | |||
4102 | /** |
||
4103 | * Gets the view, applying any `transforms` to the `start` and `end` positions. |
||
4104 | * |
||
4105 | * @private |
||
4106 | * @param {number} start The start of the view. |
||
4107 | * @param {number} end The end of the view. |
||
4108 | * @param {Array} transforms The transformations to apply to the view. |
||
4109 | * @returns {Object} Returns an object containing the `start` and `end` |
||
4110 | * positions of the view. |
||
4111 | */ |
||
4112 | function getView(start, end, transforms) { |
||
4113 | var index = -1, |
||
4114 | length = transforms.length; |
||
4115 | |||
4116 | while (++index < length) { |
||
4117 | var data = transforms[index], |
||
4118 | size = data.size; |
||
4119 | |||
4120 | switch (data.type) { |
||
4121 | case 'drop': start += size; break; |
||
4122 | case 'dropRight': end -= size; break; |
||
4123 | case 'take': end = nativeMin(end, start + size); break; |
||
4124 | case 'takeRight': start = nativeMax(start, end - size); break; |
||
4125 | } |
||
4126 | } |
||
4127 | return { 'start': start, 'end': end }; |
||
4128 | } |
||
4129 | |||
4130 | /** |
||
4131 | * Initializes an array clone. |
||
4132 | * |
||
4133 | * @private |
||
4134 | * @param {Array} array The array to clone. |
||
4135 | * @returns {Array} Returns the initialized clone. |
||
4136 | */ |
||
4137 | function initCloneArray(array) { |
||
4138 | var length = array.length, |
||
4139 | result = new array.constructor(length); |
||
4140 | |||
4141 | // Add array properties assigned by `RegExp#exec`. |
||
4142 | if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) { |
||
4143 | result.index = array.index; |
||
4144 | result.input = array.input; |
||
4145 | } |
||
4146 | return result; |
||
4147 | } |
||
4148 | |||
4149 | /** |
||
4150 | * Initializes an object clone. |
||
4151 | * |
||
4152 | * @private |
||
4153 | * @param {Object} object The object to clone. |
||
4154 | * @returns {Object} Returns the initialized clone. |
||
4155 | */ |
||
4156 | function initCloneObject(object) { |
||
4157 | var Ctor = object.constructor; |
||
4158 | if (!(typeof Ctor == 'function' && Ctor instanceof Ctor)) { |
||
4159 | Ctor = Object; |
||
4160 | } |
||
4161 | return new Ctor; |
||
4162 | } |
||
4163 | |||
4164 | /** |
||
4165 | * Initializes an object clone based on its `toStringTag`. |
||
4166 | * |
||
4167 | * **Note:** This function only supports cloning values with tags of |
||
4168 | * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. |
||
4169 | * |
||
4170 | * @private |
||
4171 | * @param {Object} object The object to clone. |
||
4172 | * @param {string} tag The `toStringTag` of the object to clone. |
||
4173 | * @param {boolean} [isDeep] Specify a deep clone. |
||
4174 | * @returns {Object} Returns the initialized clone. |
||
4175 | */ |
||
4176 | function initCloneByTag(object, tag, isDeep) { |
||
4177 | var Ctor = object.constructor; |
||
4178 | switch (tag) { |
||
4179 | case arrayBufferTag: |
||
4180 | return bufferClone(object); |
||
4181 | |||
4182 | case boolTag: |
||
4183 | case dateTag: |
||
4184 | return new Ctor(+object); |
||
4185 | |||
4186 | case float32Tag: case float64Tag: |
||
4187 | case int8Tag: case int16Tag: case int32Tag: |
||
4188 | case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag: |
||
4189 | // Safari 5 mobile incorrectly has `Object` as the constructor of typed arrays. |
||
4190 | if (Ctor instanceof Ctor) { |
||
4191 | Ctor = ctorByTag[tag]; |
||
4192 | } |
||
4193 | var buffer = object.buffer; |
||
4194 | return new Ctor(isDeep ? bufferClone(buffer) : buffer, object.byteOffset, object.length); |
||
4195 | |||
4196 | case numberTag: |
||
4197 | case stringTag: |
||
4198 | return new Ctor(object); |
||
4199 | |||
4200 | case regexpTag: |
||
4201 | var result = new Ctor(object.source, reFlags.exec(object)); |
||
4202 | result.lastIndex = object.lastIndex; |
||
4203 | } |
||
4204 | return result; |
||
4205 | } |
||
4206 | |||
4207 | /** |
||
4208 | * Invokes the method at `path` on `object`. |
||
4209 | * |
||
4210 | * @private |
||
4211 | * @param {Object} object The object to query. |
||
4212 | * @param {Array|string} path The path of the method to invoke. |
||
4213 | * @param {Array} args The arguments to invoke the method with. |
||
4214 | * @returns {*} Returns the result of the invoked method. |
||
4215 | */ |
||
4216 | function invokePath(object, path, args) { |
||
4217 | if (object != null && !isKey(path, object)) { |
||
4218 | path = toPath(path); |
||
4219 | object = path.length == 1 ? object : baseGet(object, baseSlice(path, 0, -1)); |
||
4220 | path = last(path); |
||
4221 | } |
||
4222 | var func = object == null ? object : object[path]; |
||
4223 | return func == null ? undefined : func.apply(object, args); |
||
4224 | } |
||
4225 | |||
4226 | /** |
||
4227 | * Checks if `value` is array-like. |
||
4228 | * |
||
4229 | * @private |
||
4230 | * @param {*} value The value to check. |
||
4231 | * @returns {boolean} Returns `true` if `value` is array-like, else `false`. |
||
4232 | */ |
||
4233 | function isArrayLike(value) { |
||
4234 | return value != null && isLength(getLength(value)); |
||
4235 | } |
||
4236 | |||
4237 | /** |
||
4238 | * Checks if `value` is a valid array-like index. |
||
4239 | * |
||
4240 | * @private |
||
4241 | * @param {*} value The value to check. |
||
4242 | * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index. |
||
4243 | * @returns {boolean} Returns `true` if `value` is a valid index, else `false`. |
||
4244 | */ |
||
4245 | function isIndex(value, length) { |
||
4246 | value = (typeof value == 'number' || reIsUint.test(value)) ? +value : -1; |
||
4247 | length = length == null ? MAX_SAFE_INTEGER : length; |
||
4248 | return value > -1 && value % 1 == 0 && value < length; |
||
4249 | } |
||
4250 | |||
4251 | /** |
||
4252 | * Checks if the provided arguments are from an iteratee call. |
||
4253 | * |
||
4254 | * @private |
||
4255 | * @param {*} value The potential iteratee value argument. |
||
4256 | * @param {*} index The potential iteratee index or key argument. |
||
4257 | * @param {*} object The potential iteratee object argument. |
||
4258 | * @returns {boolean} Returns `true` if the arguments are from an iteratee call, else `false`. |
||
4259 | */ |
||
4260 | function isIterateeCall(value, index, object) { |
||
4261 | if (!isObject(object)) { |
||
4262 | return false; |
||
4263 | } |
||
4264 | var type = typeof index; |
||
4265 | if (type == 'number' |
||
4266 | ? (isArrayLike(object) && isIndex(index, object.length)) |
||
4267 | : (type == 'string' && index in object)) { |
||
4268 | var other = object[index]; |
||
4269 | return value === value ? (value === other) : (other !== other); |
||
4270 | } |
||
4271 | return false; |
||
4272 | } |
||
4273 | |||
4274 | /** |
||
4275 | * Checks if `value` is a property name and not a property path. |
||
4276 | * |
||
4277 | * @private |
||
4278 | * @param {*} value The value to check. |
||
4279 | * @param {Object} [object] The object to query keys on. |
||
4280 | * @returns {boolean} Returns `true` if `value` is a property name, else `false`. |
||
4281 | */ |
||
4282 | function isKey(value, object) { |
||
4283 | var type = typeof value; |
||
4284 | if ((type == 'string' && reIsPlainProp.test(value)) || type == 'number') { |
||
4285 | return true; |
||
4286 | } |
||
4287 | if (isArray(value)) { |
||
4288 | return false; |
||
4289 | } |
||
4290 | var result = !reIsDeepProp.test(value); |
||
4291 | return result || (object != null && value in toObject(object)); |
||
4292 | } |
||
4293 | |||
4294 | /** |
||
4295 | * Checks if `func` has a lazy counterpart. |
||
4296 | * |
||
4297 | * @private |
||
4298 | * @param {Function} func The function to check. |
||
4299 | * @returns {boolean} Returns `true` if `func` has a lazy counterpart, else `false`. |
||
4300 | */ |
||
4301 | function isLaziable(func) { |
||
4302 | var funcName = getFuncName(func), |
||
4303 | other = lodash[funcName]; |
||
4304 | |||
4305 | if (typeof other != 'function' || !(funcName in LazyWrapper.prototype)) { |
||
4306 | return false; |
||
4307 | } |
||
4308 | if (func === other) { |
||
4309 | return true; |
||
4310 | } |
||
4311 | var data = getData(other); |
||
4312 | return !!data && func === data[0]; |
||
4313 | } |
||
4314 | |||
4315 | /** |
||
4316 | * Checks if `value` is a valid array-like length. |
||
4317 | * |
||
4318 | * **Note:** This function is based on [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength). |
||
4319 | * |
||
4320 | * @private |
||
4321 | * @param {*} value The value to check. |
||
4322 | * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. |
||
4323 | */ |
||
4324 | function isLength(value) { |
||
4325 | return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; |
||
4326 | } |
||
4327 | |||
4328 | /** |
||
4329 | * Checks if `value` is suitable for strict equality comparisons, i.e. `===`. |
||
4330 | * |
||
4331 | * @private |
||
4332 | * @param {*} value The value to check. |
||
4333 | * @returns {boolean} Returns `true` if `value` if suitable for strict |
||
4334 | * equality comparisons, else `false`. |
||
4335 | */ |
||
4336 | function isStrictComparable(value) { |
||
4337 | return value === value && !isObject(value); |
||
4338 | } |
||
4339 | |||
4340 | /** |
||
4341 | * Merges the function metadata of `source` into `data`. |
||
4342 | * |
||
4343 | * Merging metadata reduces the number of wrappers required to invoke a function. |
||
4344 | * This is possible because methods like `_.bind`, `_.curry`, and `_.partial` |
||
4345 | * may be applied regardless of execution order. Methods like `_.ary` and `_.rearg` |
||
4346 | * augment function arguments, making the order in which they are executed important, |
||
4347 | * preventing the merging of metadata. However, we make an exception for a safe |
||
4348 | * common case where curried functions have `_.ary` and or `_.rearg` applied. |
||
4349 | * |
||
4350 | * @private |
||
4351 | * @param {Array} data The destination metadata. |
||
4352 | * @param {Array} source The source metadata. |
||
4353 | * @returns {Array} Returns `data`. |
||
4354 | */ |
||
4355 | function mergeData(data, source) { |
||
4356 | var bitmask = data[1], |
||
4357 | srcBitmask = source[1], |
||
4358 | newBitmask = bitmask | srcBitmask, |
||
4359 | isCommon = newBitmask < ARY_FLAG; |
||
4360 | |||
4361 | var isCombo = |
||
4362 | (srcBitmask == ARY_FLAG && bitmask == CURRY_FLAG) || |
||
4363 | (srcBitmask == ARY_FLAG && bitmask == REARG_FLAG && data[7].length <= source[8]) || |
||
4364 | (srcBitmask == (ARY_FLAG | REARG_FLAG) && bitmask == CURRY_FLAG); |
||
4365 | |||
4366 | // Exit early if metadata can't be merged. |
||
4367 | if (!(isCommon || isCombo)) { |
||
4368 | return data; |
||
4369 | } |
||
4370 | // Use source `thisArg` if available. |
||
4371 | if (srcBitmask & BIND_FLAG) { |
||
4372 | data[2] = source[2]; |
||
4373 | // Set when currying a bound function. |
||
4374 | newBitmask |= (bitmask & BIND_FLAG) ? 0 : CURRY_BOUND_FLAG; |
||
4375 | } |
||
4376 | // Compose partial arguments. |
||
4377 | var value = source[3]; |
||
4378 | if (value) { |
||
4379 | var partials = data[3]; |
||
4380 | data[3] = partials ? composeArgs(partials, value, source[4]) : arrayCopy(value); |
||
4381 | data[4] = partials ? replaceHolders(data[3], PLACEHOLDER) : arrayCopy(source[4]); |
||
4382 | } |
||
4383 | // Compose partial right arguments. |
||
4384 | value = source[5]; |
||
4385 | if (value) { |
||
4386 | partials = data[5]; |
||
4387 | data[5] = partials ? composeArgsRight(partials, value, source[6]) : arrayCopy(value); |
||
4388 | data[6] = partials ? replaceHolders(data[5], PLACEHOLDER) : arrayCopy(source[6]); |
||
4389 | } |
||
4390 | // Use source `argPos` if available. |
||
4391 | value = source[7]; |
||
4392 | if (value) { |
||
4393 | data[7] = arrayCopy(value); |
||
4394 | } |
||
4395 | // Use source `ary` if it's smaller. |
||
4396 | if (srcBitmask & ARY_FLAG) { |
||
4397 | data[8] = data[8] == null ? source[8] : nativeMin(data[8], source[8]); |
||
4398 | } |
||
4399 | // Use source `arity` if one is not provided. |
||
4400 | if (data[9] == null) { |
||
4401 | data[9] = source[9]; |
||
4402 | } |
||
4403 | // Use source `func` and merge bitmasks. |
||
4404 | data[0] = source[0]; |
||
4405 | data[1] = newBitmask; |
||
4406 | |||
4407 | return data; |
||
4408 | } |
||
4409 | |||
4410 | /** |
||
4411 | * Used by `_.defaultsDeep` to customize its `_.merge` use. |
||
4412 | * |
||
4413 | * @private |
||
4414 | * @param {*} objectValue The destination object property value. |
||
4415 | * @param {*} sourceValue The source object property value. |
||
4416 | * @returns {*} Returns the value to assign to the destination object. |
||
4417 | */ |
||
4418 | function mergeDefaults(objectValue, sourceValue) { |
||
4419 | return objectValue === undefined ? sourceValue : merge(objectValue, sourceValue, mergeDefaults); |
||
4420 | } |
||
4421 | |||
4422 | /** |
||
4423 | * A specialized version of `_.pick` which picks `object` properties specified |
||
4424 | * by `props`. |
||
4425 | * |
||
4426 | * @private |
||
4427 | * @param {Object} object The source object. |
||
4428 | * @param {string[]} props The property names to pick. |
||
4429 | * @returns {Object} Returns the new object. |
||
4430 | */ |
||
4431 | function pickByArray(object, props) { |
||
4432 | object = toObject(object); |
||
4433 | |||
4434 | var index = -1, |
||
4435 | length = props.length, |
||
4436 | result = {}; |
||
4437 | |||
4438 | while (++index < length) { |
||
4439 | var key = props[index]; |
||
4440 | if (key in object) { |
||
4441 | result[key] = object[key]; |
||
4442 | } |
||
4443 | } |
||
4444 | return result; |
||
4445 | } |
||
4446 | |||
4447 | /** |
||
4448 | * A specialized version of `_.pick` which picks `object` properties `predicate` |
||
4449 | * returns truthy for. |
||
4450 | * |
||
4451 | * @private |
||
4452 | * @param {Object} object The source object. |
||
4453 | * @param {Function} predicate The function invoked per iteration. |
||
4454 | * @returns {Object} Returns the new object. |
||
4455 | */ |
||
4456 | function pickByCallback(object, predicate) { |
||
4457 | var result = {}; |
||
4458 | baseForIn(object, function(value, key, object) { |
||
4459 | if (predicate(value, key, object)) { |
||
4460 | result[key] = value; |
||
4461 | } |
||
4462 | }); |
||
4463 | return result; |
||
4464 | } |
||
4465 | |||
4466 | /** |
||
4467 | * Reorder `array` according to the specified indexes where the element at |
||
4468 | * the first index is assigned as the first element, the element at |
||
4469 | * the second index is assigned as the second element, and so on. |
||
4470 | * |
||
4471 | * @private |
||
4472 | * @param {Array} array The array to reorder. |
||
4473 | * @param {Array} indexes The arranged array indexes. |
||
4474 | * @returns {Array} Returns `array`. |
||
4475 | */ |
||
4476 | function reorder(array, indexes) { |
||
4477 | var arrLength = array.length, |
||
4478 | length = nativeMin(indexes.length, arrLength), |
||
4479 | oldArray = arrayCopy(array); |
||
4480 | |||
4481 | while (length--) { |
||
4482 | var index = indexes[length]; |
||
4483 | array[length] = isIndex(index, arrLength) ? oldArray[index] : undefined; |
||
4484 | } |
||
4485 | return array; |
||
4486 | } |
||
4487 | |||
4488 | /** |
||
4489 | * Sets metadata for `func`. |
||
4490 | * |
||
4491 | * **Note:** If this function becomes hot, i.e. is invoked a lot in a short |
||
4492 | * period of time, it will trip its breaker and transition to an identity function |
||
4493 | * to avoid garbage collection pauses in V8. See [V8 issue 2070](https://code.google.com/p/v8/issues/detail?id=2070) |
||
4494 | * for more details. |
||
4495 | * |
||
4496 | * @private |
||
4497 | * @param {Function} func The function to associate metadata with. |
||
4498 | * @param {*} data The metadata. |
||
4499 | * @returns {Function} Returns `func`. |
||
4500 | */ |
||
4501 | var setData = (function() { |
||
4502 | var count = 0, |
||
4503 | lastCalled = 0; |
||
4504 | |||
4505 | return function(key, value) { |
||
4506 | var stamp = now(), |
||
4507 | remaining = HOT_SPAN - (stamp - lastCalled); |
||
4508 | |||
4509 | lastCalled = stamp; |
||
4510 | if (remaining > 0) { |
||
4511 | if (++count >= HOT_COUNT) { |
||
4512 | return key; |
||
4513 | } |
||
4514 | } else { |
||
4515 | count = 0; |
||
4516 | } |
||
4517 | return baseSetData(key, value); |
||
4518 | }; |
||
4519 | }()); |
||
4520 | |||
4521 | /** |
||
4522 | * A fallback implementation of `Object.keys` which creates an array of the |
||
4523 | * own enumerable property names of `object`. |
||
4524 | * |
||
4525 | * @private |
||
4526 | * @param {Object} object The object to query. |
||
4527 | * @returns {Array} Returns the array of property names. |
||
4528 | */ |
||
4529 | function shimKeys(object) { |
||
4530 | var props = keysIn(object), |
||
4531 | propsLength = props.length, |
||
4532 | length = propsLength && object.length; |
||
4533 | |||
4534 | var allowIndexes = !!length && isLength(length) && |
||
4535 | (isArray(object) || isArguments(object) || isString(object)); |
||
4536 | |||
4537 | var index = -1, |
||
4538 | result = []; |
||
4539 | |||
4540 | while (++index < propsLength) { |
||
4541 | var key = props[index]; |
||
4542 | if ((allowIndexes && isIndex(key, length)) || hasOwnProperty.call(object, key)) { |
||
4543 | result.push(key); |
||
4544 | } |
||
4545 | } |
||
4546 | return result; |
||
4547 | } |
||
4548 | |||
4549 | /** |
||
4550 | * Converts `value` to an array-like object if it's not one. |
||
4551 | * |
||
4552 | * @private |
||
4553 | * @param {*} value The value to process. |
||
4554 | * @returns {Array|Object} Returns the array-like object. |
||
4555 | */ |
||
4556 | function toIterable(value) { |
||
4557 | if (value == null) { |
||
4558 | return []; |
||
4559 | } |
||
4560 | if (!isArrayLike(value)) { |
||
4561 | return values(value); |
||
4562 | } |
||
4563 | if (lodash.support.unindexedChars && isString(value)) { |
||
4564 | return value.split(''); |
||
4565 | } |
||
4566 | return isObject(value) ? value : Object(value); |
||
4567 | } |
||
4568 | |||
4569 | /** |
||
4570 | * Converts `value` to an object if it's not one. |
||
4571 | * |
||
4572 | * @private |
||
4573 | * @param {*} value The value to process. |
||
4574 | * @returns {Object} Returns the object. |
||
4575 | */ |
||
4576 | function toObject(value) { |
||
4577 | if (lodash.support.unindexedChars && isString(value)) { |
||
4578 | var index = -1, |
||
4579 | length = value.length, |
||
4580 | result = Object(value); |
||
4581 | |||
4582 | while (++index < length) { |
||
4583 | result[index] = value.charAt(index); |
||
4584 | } |
||
4585 | return result; |
||
4586 | } |
||
4587 | return isObject(value) ? value : Object(value); |
||
4588 | } |
||
4589 | |||
4590 | /** |
||
4591 | * Converts `value` to property path array if it's not one. |
||
4592 | * |
||
4593 | * @private |
||
4594 | * @param {*} value The value to process. |
||
4595 | * @returns {Array} Returns the property path array. |
||
4596 | */ |
||
4597 | function toPath(value) { |
||
4598 | if (isArray(value)) { |
||
4599 | return value; |
||
4600 | } |
||
4601 | var result = []; |
||
4602 | baseToString(value).replace(rePropName, function(match, number, quote, string) { |
||
4603 | result.push(quote ? string.replace(reEscapeChar, '$1') : (number || match)); |
||
4604 | }); |
||
4605 | return result; |
||
4606 | } |
||
4607 | |||
4608 | /** |
||
4609 | * Creates a clone of `wrapper`. |
||
4610 | * |
||
4611 | * @private |
||
4612 | * @param {Object} wrapper The wrapper to clone. |
||
4613 | * @returns {Object} Returns the cloned wrapper. |
||
4614 | */ |
||
4615 | function wrapperClone(wrapper) { |
||
4616 | return wrapper instanceof LazyWrapper |
||
4617 | ? wrapper.clone() |
||
4618 | : new LodashWrapper(wrapper.__wrapped__, wrapper.__chain__, arrayCopy(wrapper.__actions__)); |
||
4619 | } |
||
4620 | |||
4621 | /*------------------------------------------------------------------------*/ |
||
4622 | |||
4623 | /** |
||
4624 | * Creates an array of elements split into groups the length of `size`. |
||
4625 | * If `collection` can't be split evenly, the final chunk will be the remaining |
||
4626 | * elements. |
||
4627 | * |
||
4628 | * @static |
||
4629 | * @memberOf _ |
||
4630 | * @category Array |
||
4631 | * @param {Array} array The array to process. |
||
4632 | * @param {number} [size=1] The length of each chunk. |
||
4633 | * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. |
||
4634 | * @returns {Array} Returns the new array containing chunks. |
||
4635 | * @example |
||
4636 | * |
||
4637 | * _.chunk(['a', 'b', 'c', 'd'], 2); |
||
4638 | * // => [['a', 'b'], ['c', 'd']] |
||
4639 | * |
||
4640 | * _.chunk(['a', 'b', 'c', 'd'], 3); |
||
4641 | * // => [['a', 'b', 'c'], ['d']] |
||
4642 | */ |
||
4643 | function chunk(array, size, guard) { |
||
4644 | if (guard ? isIterateeCall(array, size, guard) : size == null) { |
||
4645 | size = 1; |
||
4646 | } else { |
||
4647 | size = nativeMax(nativeFloor(size) || 1, 1); |
||
4648 | } |
||
4649 | var index = 0, |
||
4650 | length = array ? array.length : 0, |
||
4651 | resIndex = -1, |
||
4652 | result = Array(nativeCeil(length / size)); |
||
4653 | |||
4654 | while (index < length) { |
||
4655 | result[++resIndex] = baseSlice(array, index, (index += size)); |
||
4656 | } |
||
4657 | return result; |
||
4658 | } |
||
4659 | |||
4660 | /** |
||
4661 | * Creates an array with all falsey values removed. The values `false`, `null`, |
||
4662 | * `0`, `""`, `undefined`, and `NaN` are falsey. |
||
4663 | * |
||
4664 | * @static |
||
4665 | * @memberOf _ |
||
4666 | * @category Array |
||
4667 | * @param {Array} array The array to compact. |
||
4668 | * @returns {Array} Returns the new array of filtered values. |
||
4669 | * @example |
||
4670 | * |
||
4671 | * _.compact([0, 1, false, 2, '', 3]); |
||
4672 | * // => [1, 2, 3] |
||
4673 | */ |
||
4674 | function compact(array) { |
||
4675 | var index = -1, |
||
4676 | length = array ? array.length : 0, |
||
4677 | resIndex = -1, |
||
4678 | result = []; |
||
4679 | |||
4680 | while (++index < length) { |
||
4681 | var value = array[index]; |
||
4682 | if (value) { |
||
4683 | result[++resIndex] = value; |
||
4684 | } |
||
4685 | } |
||
4686 | return result; |
||
4687 | } |
||
4688 | |||
4689 | /** |
||
4690 | * Creates an array of unique `array` values not included in the other |
||
4691 | * provided arrays using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) |
||
4692 | * for equality comparisons. |
||
4693 | * |
||
4694 | * @static |
||
4695 | * @memberOf _ |
||
4696 | * @category Array |
||
4697 | * @param {Array} array The array to inspect. |
||
4698 | * @param {...Array} [values] The arrays of values to exclude. |
||
4699 | * @returns {Array} Returns the new array of filtered values. |
||
4700 | * @example |
||
4701 | * |
||
4702 | * _.difference([1, 2, 3], [4, 2]); |
||
4703 | * // => [1, 3] |
||
4704 | */ |
||
4705 | var difference = restParam(function(array, values) { |
||
4706 | return (isObjectLike(array) && isArrayLike(array)) |
||
4707 | ? baseDifference(array, baseFlatten(values, false, true)) |
||
4708 | : []; |
||
4709 | }); |
||
4710 | |||
4711 | /** |
||
4712 | * Creates a slice of `array` with `n` elements dropped from the beginning. |
||
4713 | * |
||
4714 | * @static |
||
4715 | * @memberOf _ |
||
4716 | * @category Array |
||
4717 | * @param {Array} array The array to query. |
||
4718 | * @param {number} [n=1] The number of elements to drop. |
||
4719 | * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. |
||
4720 | * @returns {Array} Returns the slice of `array`. |
||
4721 | * @example |
||
4722 | * |
||
4723 | * _.drop([1, 2, 3]); |
||
4724 | * // => [2, 3] |
||
4725 | * |
||
4726 | * _.drop([1, 2, 3], 2); |
||
4727 | * // => [3] |
||
4728 | * |
||
4729 | * _.drop([1, 2, 3], 5); |
||
4730 | * // => [] |
||
4731 | * |
||
4732 | * _.drop([1, 2, 3], 0); |
||
4733 | * // => [1, 2, 3] |
||
4734 | */ |
||
4735 | function drop(array, n, guard) { |
||
4736 | var length = array ? array.length : 0; |
||
4737 | if (!length) { |
||
4738 | return []; |
||
4739 | } |
||
4740 | if (guard ? isIterateeCall(array, n, guard) : n == null) { |
||
4741 | n = 1; |
||
4742 | } |
||
4743 | return baseSlice(array, n < 0 ? 0 : n); |
||
4744 | } |
||
4745 | |||
4746 | /** |
||
4747 | * Creates a slice of `array` with `n` elements dropped from the end. |
||
4748 | * |
||
4749 | * @static |
||
4750 | * @memberOf _ |
||
4751 | * @category Array |
||
4752 | * @param {Array} array The array to query. |
||
4753 | * @param {number} [n=1] The number of elements to drop. |
||
4754 | * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. |
||
4755 | * @returns {Array} Returns the slice of `array`. |
||
4756 | * @example |
||
4757 | * |
||
4758 | * _.dropRight([1, 2, 3]); |
||
4759 | * // => [1, 2] |
||
4760 | * |
||
4761 | * _.dropRight([1, 2, 3], 2); |
||
4762 | * // => [1] |
||
4763 | * |
||
4764 | * _.dropRight([1, 2, 3], 5); |
||
4765 | * // => [] |
||
4766 | * |
||
4767 | * _.dropRight([1, 2, 3], 0); |
||
4768 | * // => [1, 2, 3] |
||
4769 | */ |
||
4770 | View Code Duplication | function dropRight(array, n, guard) { |
|
4771 | var length = array ? array.length : 0; |
||
4772 | if (!length) { |
||
4773 | return []; |
||
4774 | } |
||
4775 | if (guard ? isIterateeCall(array, n, guard) : n == null) { |
||
4776 | n = 1; |
||
4777 | } |
||
4778 | n = length - (+n || 0); |
||
4779 | return baseSlice(array, 0, n < 0 ? 0 : n); |
||
4780 | } |
||
4781 | |||
4782 | /** |
||
4783 | * Creates a slice of `array` excluding elements dropped from the end. |
||
4784 | * Elements are dropped until `predicate` returns falsey. The predicate is |
||
4785 | * bound to `thisArg` and invoked with three arguments: (value, index, array). |
||
4786 | * |
||
4787 | * If a property name is provided for `predicate` the created `_.property` |
||
4788 | * style callback returns the property value of the given element. |
||
4789 | * |
||
4790 | * If a value is also provided for `thisArg` the created `_.matchesProperty` |
||
4791 | * style callback returns `true` for elements that have a matching property |
||
4792 | * value, else `false`. |
||
4793 | * |
||
4794 | * If an object is provided for `predicate` the created `_.matches` style |
||
4795 | * callback returns `true` for elements that match the properties of the given |
||
4796 | * object, else `false`. |
||
4797 | * |
||
4798 | * @static |
||
4799 | * @memberOf _ |
||
4800 | * @category Array |
||
4801 | * @param {Array} array The array to query. |
||
4802 | * @param {Function|Object|string} [predicate=_.identity] The function invoked |
||
4803 | * per iteration. |
||
4804 | * @param {*} [thisArg] The `this` binding of `predicate`. |
||
4805 | * @returns {Array} Returns the slice of `array`. |
||
4806 | * @example |
||
4807 | * |
||
4808 | * _.dropRightWhile([1, 2, 3], function(n) { |
||
4809 | * return n > 1; |
||
4810 | * }); |
||
4811 | * // => [1] |
||
4812 | * |
||
4813 | * var users = [ |
||
4814 | * { 'user': 'barney', 'active': true }, |
||
4815 | * { 'user': 'fred', 'active': false }, |
||
4816 | * { 'user': 'pebbles', 'active': false } |
||
4817 | * ]; |
||
4818 | * |
||
4819 | * // using the `_.matches` callback shorthand |
||
4820 | * _.pluck(_.dropRightWhile(users, { 'user': 'pebbles', 'active': false }), 'user'); |
||
4821 | * // => ['barney', 'fred'] |
||
4822 | * |
||
4823 | * // using the `_.matchesProperty` callback shorthand |
||
4824 | * _.pluck(_.dropRightWhile(users, 'active', false), 'user'); |
||
4825 | * // => ['barney'] |
||
4826 | * |
||
4827 | * // using the `_.property` callback shorthand |
||
4828 | * _.pluck(_.dropRightWhile(users, 'active'), 'user'); |
||
4829 | * // => ['barney', 'fred', 'pebbles'] |
||
4830 | */ |
||
4831 | function dropRightWhile(array, predicate, thisArg) { |
||
4832 | return (array && array.length) |
||
4833 | ? baseWhile(array, getCallback(predicate, thisArg, 3), true, true) |
||
4834 | : []; |
||
4835 | } |
||
4836 | |||
4837 | /** |
||
4838 | * Creates a slice of `array` excluding elements dropped from the beginning. |
||
4839 | * Elements are dropped until `predicate` returns falsey. The predicate is |
||
4840 | * bound to `thisArg` and invoked with three arguments: (value, index, array). |
||
4841 | * |
||
4842 | * If a property name is provided for `predicate` the created `_.property` |
||
4843 | * style callback returns the property value of the given element. |
||
4844 | * |
||
4845 | * If a value is also provided for `thisArg` the created `_.matchesProperty` |
||
4846 | * style callback returns `true` for elements that have a matching property |
||
4847 | * value, else `false`. |
||
4848 | * |
||
4849 | * If an object is provided for `predicate` the created `_.matches` style |
||
4850 | * callback returns `true` for elements that have the properties of the given |
||
4851 | * object, else `false`. |
||
4852 | * |
||
4853 | * @static |
||
4854 | * @memberOf _ |
||
4855 | * @category Array |
||
4856 | * @param {Array} array The array to query. |
||
4857 | * @param {Function|Object|string} [predicate=_.identity] The function invoked |
||
4858 | * per iteration. |
||
4859 | * @param {*} [thisArg] The `this` binding of `predicate`. |
||
4860 | * @returns {Array} Returns the slice of `array`. |
||
4861 | * @example |
||
4862 | * |
||
4863 | * _.dropWhile([1, 2, 3], function(n) { |
||
4864 | * return n < 3; |
||
4865 | * }); |
||
4866 | * // => [3] |
||
4867 | * |
||
4868 | * var users = [ |
||
4869 | * { 'user': 'barney', 'active': false }, |
||
4870 | * { 'user': 'fred', 'active': false }, |
||
4871 | * { 'user': 'pebbles', 'active': true } |
||
4872 | * ]; |
||
4873 | * |
||
4874 | * // using the `_.matches` callback shorthand |
||
4875 | * _.pluck(_.dropWhile(users, { 'user': 'barney', 'active': false }), 'user'); |
||
4876 | * // => ['fred', 'pebbles'] |
||
4877 | * |
||
4878 | * // using the `_.matchesProperty` callback shorthand |
||
4879 | * _.pluck(_.dropWhile(users, 'active', false), 'user'); |
||
4880 | * // => ['pebbles'] |
||
4881 | * |
||
4882 | * // using the `_.property` callback shorthand |
||
4883 | * _.pluck(_.dropWhile(users, 'active'), 'user'); |
||
4884 | * // => ['barney', 'fred', 'pebbles'] |
||
4885 | */ |
||
4886 | function dropWhile(array, predicate, thisArg) { |
||
4887 | return (array && array.length) |
||
4888 | ? baseWhile(array, getCallback(predicate, thisArg, 3), true) |
||
4889 | : []; |
||
4890 | } |
||
4891 | |||
4892 | /** |
||
4893 | * Fills elements of `array` with `value` from `start` up to, but not |
||
4894 | * including, `end`. |
||
4895 | * |
||
4896 | * **Note:** This method mutates `array`. |
||
4897 | * |
||
4898 | * @static |
||
4899 | * @memberOf _ |
||
4900 | * @category Array |
||
4901 | * @param {Array} array The array to fill. |
||
4902 | * @param {*} value The value to fill `array` with. |
||
4903 | * @param {number} [start=0] The start position. |
||
4904 | * @param {number} [end=array.length] The end position. |
||
4905 | * @returns {Array} Returns `array`. |
||
4906 | * @example |
||
4907 | * |
||
4908 | * var array = [1, 2, 3]; |
||
4909 | * |
||
4910 | * _.fill(array, 'a'); |
||
4911 | * console.log(array); |
||
4912 | * // => ['a', 'a', 'a'] |
||
4913 | * |
||
4914 | * _.fill(Array(3), 2); |
||
4915 | * // => [2, 2, 2] |
||
4916 | * |
||
4917 | * _.fill([4, 6, 8], '*', 1, 2); |
||
4918 | * // => [4, '*', 8] |
||
4919 | */ |
||
4920 | function fill(array, value, start, end) { |
||
4921 | var length = array ? array.length : 0; |
||
4922 | if (!length) { |
||
4923 | return []; |
||
4924 | } |
||
4925 | if (start && typeof start != 'number' && isIterateeCall(array, value, start)) { |
||
4926 | start = 0; |
||
4927 | end = length; |
||
4928 | } |
||
4929 | return baseFill(array, value, start, end); |
||
4930 | } |
||
4931 | |||
4932 | /** |
||
4933 | * This method is like `_.find` except that it returns the index of the first |
||
4934 | * element `predicate` returns truthy for instead of the element itself. |
||
4935 | * |
||
4936 | * If a property name is provided for `predicate` the created `_.property` |
||
4937 | * style callback returns the property value of the given element. |
||
4938 | * |
||
4939 | * If a value is also provided for `thisArg` the created `_.matchesProperty` |
||
4940 | * style callback returns `true` for elements that have a matching property |
||
4941 | * value, else `false`. |
||
4942 | * |
||
4943 | * If an object is provided for `predicate` the created `_.matches` style |
||
4944 | * callback returns `true` for elements that have the properties of the given |
||
4945 | * object, else `false`. |
||
4946 | * |
||
4947 | * @static |
||
4948 | * @memberOf _ |
||
4949 | * @category Array |
||
4950 | * @param {Array} array The array to search. |
||
4951 | * @param {Function|Object|string} [predicate=_.identity] The function invoked |
||
4952 | * per iteration. |
||
4953 | * @param {*} [thisArg] The `this` binding of `predicate`. |
||
4954 | * @returns {number} Returns the index of the found element, else `-1`. |
||
4955 | * @example |
||
4956 | * |
||
4957 | * var users = [ |
||
4958 | * { 'user': 'barney', 'active': false }, |
||
4959 | * { 'user': 'fred', 'active': false }, |
||
4960 | * { 'user': 'pebbles', 'active': true } |
||
4961 | * ]; |
||
4962 | * |
||
4963 | * _.findIndex(users, function(chr) { |
||
4964 | * return chr.user == 'barney'; |
||
4965 | * }); |
||
4966 | * // => 0 |
||
4967 | * |
||
4968 | * // using the `_.matches` callback shorthand |
||
4969 | * _.findIndex(users, { 'user': 'fred', 'active': false }); |
||
4970 | * // => 1 |
||
4971 | * |
||
4972 | * // using the `_.matchesProperty` callback shorthand |
||
4973 | * _.findIndex(users, 'active', false); |
||
4974 | * // => 0 |
||
4975 | * |
||
4976 | * // using the `_.property` callback shorthand |
||
4977 | * _.findIndex(users, 'active'); |
||
4978 | * // => 2 |
||
4979 | */ |
||
4980 | var findIndex = createFindIndex(); |
||
4981 | |||
4982 | /** |
||
4983 | * This method is like `_.findIndex` except that it iterates over elements |
||
4984 | * of `collection` from right to left. |
||
4985 | * |
||
4986 | * If a property name is provided for `predicate` the created `_.property` |
||
4987 | * style callback returns the property value of the given element. |
||
4988 | * |
||
4989 | * If a value is also provided for `thisArg` the created `_.matchesProperty` |
||
4990 | * style callback returns `true` for elements that have a matching property |
||
4991 | * value, else `false`. |
||
4992 | * |
||
4993 | * If an object is provided for `predicate` the created `_.matches` style |
||
4994 | * callback returns `true` for elements that have the properties of the given |
||
4995 | * object, else `false`. |
||
4996 | * |
||
4997 | * @static |
||
4998 | * @memberOf _ |
||
4999 | * @category Array |
||
5000 | * @param {Array} array The array to search. |
||
5001 | * @param {Function|Object|string} [predicate=_.identity] The function invoked |
||
5002 | * per iteration. |
||
5003 | * @param {*} [thisArg] The `this` binding of `predicate`. |
||
5004 | * @returns {number} Returns the index of the found element, else `-1`. |
||
5005 | * @example |
||
5006 | * |
||
5007 | * var users = [ |
||
5008 | * { 'user': 'barney', 'active': true }, |
||
5009 | * { 'user': 'fred', 'active': false }, |
||
5010 | * { 'user': 'pebbles', 'active': false } |
||
5011 | * ]; |
||
5012 | * |
||
5013 | * _.findLastIndex(users, function(chr) { |
||
5014 | * return chr.user == 'pebbles'; |
||
5015 | * }); |
||
5016 | * // => 2 |
||
5017 | * |
||
5018 | * // using the `_.matches` callback shorthand |
||
5019 | * _.findLastIndex(users, { 'user': 'barney', 'active': true }); |
||
5020 | * // => 0 |
||
5021 | * |
||
5022 | * // using the `_.matchesProperty` callback shorthand |
||
5023 | * _.findLastIndex(users, 'active', false); |
||
5024 | * // => 2 |
||
5025 | * |
||
5026 | * // using the `_.property` callback shorthand |
||
5027 | * _.findLastIndex(users, 'active'); |
||
5028 | * // => 0 |
||
5029 | */ |
||
5030 | var findLastIndex = createFindIndex(true); |
||
5031 | |||
5032 | /** |
||
5033 | * Gets the first element of `array`. |
||
5034 | * |
||
5035 | * @static |
||
5036 | * @memberOf _ |
||
5037 | * @alias head |
||
5038 | * @category Array |
||
5039 | * @param {Array} array The array to query. |
||
5040 | * @returns {*} Returns the first element of `array`. |
||
5041 | * @example |
||
5042 | * |
||
5043 | * _.first([1, 2, 3]); |
||
5044 | * // => 1 |
||
5045 | * |
||
5046 | * _.first([]); |
||
5047 | * // => undefined |
||
5048 | */ |
||
5049 | function first(array) { |
||
5050 | return array ? array[0] : undefined; |
||
5051 | } |
||
5052 | |||
5053 | /** |
||
5054 | * Flattens a nested array. If `isDeep` is `true` the array is recursively |
||
5055 | * flattened, otherwise it's only flattened a single level. |
||
5056 | * |
||
5057 | * @static |
||
5058 | * @memberOf _ |
||
5059 | * @category Array |
||
5060 | * @param {Array} array The array to flatten. |
||
5061 | * @param {boolean} [isDeep] Specify a deep flatten. |
||
5062 | * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. |
||
5063 | * @returns {Array} Returns the new flattened array. |
||
5064 | * @example |
||
5065 | * |
||
5066 | * _.flatten([1, [2, 3, [4]]]); |
||
5067 | * // => [1, 2, 3, [4]] |
||
5068 | * |
||
5069 | * // using `isDeep` |
||
5070 | * _.flatten([1, [2, 3, [4]]], true); |
||
5071 | * // => [1, 2, 3, 4] |
||
5072 | */ |
||
5073 | function flatten(array, isDeep, guard) { |
||
5074 | var length = array ? array.length : 0; |
||
5075 | if (guard && isIterateeCall(array, isDeep, guard)) { |
||
5076 | isDeep = false; |
||
5077 | } |
||
5078 | return length ? baseFlatten(array, isDeep) : []; |
||
5079 | } |
||
5080 | |||
5081 | /** |
||
5082 | * Recursively flattens a nested array. |
||
5083 | * |
||
5084 | * @static |
||
5085 | * @memberOf _ |
||
5086 | * @category Array |
||
5087 | * @param {Array} array The array to recursively flatten. |
||
5088 | * @returns {Array} Returns the new flattened array. |
||
5089 | * @example |
||
5090 | * |
||
5091 | * _.flattenDeep([1, [2, 3, [4]]]); |
||
5092 | * // => [1, 2, 3, 4] |
||
5093 | */ |
||
5094 | function flattenDeep(array) { |
||
5095 | var length = array ? array.length : 0; |
||
5096 | return length ? baseFlatten(array, true) : []; |
||
5097 | } |
||
5098 | |||
5099 | /** |
||
5100 | * Gets the index at which the first occurrence of `value` is found in `array` |
||
5101 | * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) |
||
5102 | * for equality comparisons. If `fromIndex` is negative, it's used as the offset |
||
5103 | * from the end of `array`. If `array` is sorted providing `true` for `fromIndex` |
||
5104 | * performs a faster binary search. |
||
5105 | * |
||
5106 | * @static |
||
5107 | * @memberOf _ |
||
5108 | * @category Array |
||
5109 | * @param {Array} array The array to search. |
||
5110 | * @param {*} value The value to search for. |
||
5111 | * @param {boolean|number} [fromIndex=0] The index to search from or `true` |
||
5112 | * to perform a binary search on a sorted array. |
||
5113 | * @returns {number} Returns the index of the matched value, else `-1`. |
||
5114 | * @example |
||
5115 | * |
||
5116 | * _.indexOf([1, 2, 1, 2], 2); |
||
5117 | * // => 1 |
||
5118 | * |
||
5119 | * // using `fromIndex` |
||
5120 | * _.indexOf([1, 2, 1, 2], 2, 2); |
||
5121 | * // => 3 |
||
5122 | * |
||
5123 | * // performing a binary search |
||
5124 | * _.indexOf([1, 1, 2, 2], 2, true); |
||
5125 | * // => 2 |
||
5126 | */ |
||
5127 | function indexOf(array, value, fromIndex) { |
||
5128 | var length = array ? array.length : 0; |
||
5129 | if (!length) { |
||
5130 | return -1; |
||
5131 | } |
||
5132 | if (typeof fromIndex == 'number') { |
||
5133 | fromIndex = fromIndex < 0 ? nativeMax(length + fromIndex, 0) : fromIndex; |
||
5134 | } else if (fromIndex) { |
||
5135 | var index = binaryIndex(array, value); |
||
5136 | if (index < length && |
||
5137 | (value === value ? (value === array[index]) : (array[index] !== array[index]))) { |
||
5138 | return index; |
||
5139 | } |
||
5140 | return -1; |
||
5141 | } |
||
5142 | return baseIndexOf(array, value, fromIndex || 0); |
||
5143 | } |
||
5144 | |||
5145 | /** |
||
5146 | * Gets all but the last element of `array`. |
||
5147 | * |
||
5148 | * @static |
||
5149 | * @memberOf _ |
||
5150 | * @category Array |
||
5151 | * @param {Array} array The array to query. |
||
5152 | * @returns {Array} Returns the slice of `array`. |
||
5153 | * @example |
||
5154 | * |
||
5155 | * _.initial([1, 2, 3]); |
||
5156 | * // => [1, 2] |
||
5157 | */ |
||
5158 | function initial(array) { |
||
5159 | return dropRight(array, 1); |
||
5160 | } |
||
5161 | |||
5162 | /** |
||
5163 | * Creates an array of unique values that are included in all of the provided |
||
5164 | * arrays using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) |
||
5165 | * for equality comparisons. |
||
5166 | * |
||
5167 | * @static |
||
5168 | * @memberOf _ |
||
5169 | * @category Array |
||
5170 | * @param {...Array} [arrays] The arrays to inspect. |
||
5171 | * @returns {Array} Returns the new array of shared values. |
||
5172 | * @example |
||
5173 | * _.intersection([1, 2], [4, 2], [2, 1]); |
||
5174 | * // => [2] |
||
5175 | */ |
||
5176 | var intersection = restParam(function(arrays) { |
||
5177 | var othLength = arrays.length, |
||
5178 | othIndex = othLength, |
||
5179 | caches = Array(length), |
||
5180 | indexOf = getIndexOf(), |
||
5181 | isCommon = indexOf === baseIndexOf, |
||
5182 | result = []; |
||
5183 | |||
5184 | while (othIndex--) { |
||
5185 | var value = arrays[othIndex] = isArrayLike(value = arrays[othIndex]) ? value : []; |
||
5186 | caches[othIndex] = (isCommon && value.length >= 120) ? createCache(othIndex && value) : null; |
||
5187 | } |
||
5188 | var array = arrays[0], |
||
5189 | index = -1, |
||
5190 | length = array ? array.length : 0, |
||
5191 | seen = caches[0]; |
||
5192 | |||
5193 | outer: |
||
5194 | while (++index < length) { |
||
5195 | value = array[index]; |
||
5196 | if ((seen ? cacheIndexOf(seen, value) : indexOf(result, value, 0)) < 0) { |
||
5197 | var othIndex = othLength; |
||
5198 | while (--othIndex) { |
||
5199 | var cache = caches[othIndex]; |
||
5200 | if ((cache ? cacheIndexOf(cache, value) : indexOf(arrays[othIndex], value, 0)) < 0) { |
||
5201 | continue outer; |
||
5202 | } |
||
5203 | } |
||
5204 | if (seen) { |
||
5205 | seen.push(value); |
||
5206 | } |
||
5207 | result.push(value); |
||
5208 | } |
||
5209 | } |
||
5210 | return result; |
||
5211 | }); |
||
5212 | |||
5213 | /** |
||
5214 | * Gets the last element of `array`. |
||
5215 | * |
||
5216 | * @static |
||
5217 | * @memberOf _ |
||
5218 | * @category Array |
||
5219 | * @param {Array} array The array to query. |
||
5220 | * @returns {*} Returns the last element of `array`. |
||
5221 | * @example |
||
5222 | * |
||
5223 | * _.last([1, 2, 3]); |
||
5224 | * // => 3 |
||
5225 | */ |
||
5226 | function last(array) { |
||
5227 | var length = array ? array.length : 0; |
||
5228 | return length ? array[length - 1] : undefined; |
||
5229 | } |
||
5230 | |||
5231 | /** |
||
5232 | * This method is like `_.indexOf` except that it iterates over elements of |
||
5233 | * `array` from right to left. |
||
5234 | * |
||
5235 | * @static |
||
5236 | * @memberOf _ |
||
5237 | * @category Array |
||
5238 | * @param {Array} array The array to search. |
||
5239 | * @param {*} value The value to search for. |
||
5240 | * @param {boolean|number} [fromIndex=array.length-1] The index to search from |
||
5241 | * or `true` to perform a binary search on a sorted array. |
||
5242 | * @returns {number} Returns the index of the matched value, else `-1`. |
||
5243 | * @example |
||
5244 | * |
||
5245 | * _.lastIndexOf([1, 2, 1, 2], 2); |
||
5246 | * // => 3 |
||
5247 | * |
||
5248 | * // using `fromIndex` |
||
5249 | * _.lastIndexOf([1, 2, 1, 2], 2, 2); |
||
5250 | * // => 1 |
||
5251 | * |
||
5252 | * // performing a binary search |
||
5253 | * _.lastIndexOf([1, 1, 2, 2], 2, true); |
||
5254 | * // => 3 |
||
5255 | */ |
||
5256 | function lastIndexOf(array, value, fromIndex) { |
||
5257 | var length = array ? array.length : 0; |
||
5258 | if (!length) { |
||
5259 | return -1; |
||
5260 | } |
||
5261 | var index = length; |
||
5262 | if (typeof fromIndex == 'number') { |
||
5263 | index = (fromIndex < 0 ? nativeMax(length + fromIndex, 0) : nativeMin(fromIndex || 0, length - 1)) + 1; |
||
5264 | } else if (fromIndex) { |
||
5265 | index = binaryIndex(array, value, true) - 1; |
||
5266 | var other = array[index]; |
||
5267 | if (value === value ? (value === other) : (other !== other)) { |
||
5268 | return index; |
||
5269 | } |
||
5270 | return -1; |
||
5271 | } |
||
5272 | if (value !== value) { |
||
5273 | return indexOfNaN(array, index, true); |
||
5274 | } |
||
5275 | while (index--) { |
||
5276 | if (array[index] === value) { |
||
5277 | return index; |
||
5278 | } |
||
5279 | } |
||
5280 | return -1; |
||
5281 | } |
||
5282 | |||
5283 | /** |
||
5284 | * Removes all provided values from `array` using |
||
5285 | * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) |
||
5286 | * for equality comparisons. |
||
5287 | * |
||
5288 | * **Note:** Unlike `_.without`, this method mutates `array`. |
||
5289 | * |
||
5290 | * @static |
||
5291 | * @memberOf _ |
||
5292 | * @category Array |
||
5293 | * @param {Array} array The array to modify. |
||
5294 | * @param {...*} [values] The values to remove. |
||
5295 | * @returns {Array} Returns `array`. |
||
5296 | * @example |
||
5297 | * |
||
5298 | * var array = [1, 2, 3, 1, 2, 3]; |
||
5299 | * |
||
5300 | * _.pull(array, 2, 3); |
||
5301 | * console.log(array); |
||
5302 | * // => [1, 1] |
||
5303 | */ |
||
5304 | function pull() { |
||
5305 | var args = arguments, |
||
5306 | array = args[0]; |
||
5307 | |||
5308 | if (!(array && array.length)) { |
||
5309 | return array; |
||
5310 | } |
||
5311 | var index = 0, |
||
5312 | indexOf = getIndexOf(), |
||
5313 | length = args.length; |
||
5314 | |||
5315 | while (++index < length) { |
||
5316 | var fromIndex = 0, |
||
5317 | value = args[index]; |
||
5318 | |||
5319 | while ((fromIndex = indexOf(array, value, fromIndex)) > -1) { |
||
5320 | splice.call(array, fromIndex, 1); |
||
5321 | } |
||
5322 | } |
||
5323 | return array; |
||
5324 | } |
||
5325 | |||
5326 | /** |
||
5327 | * Removes elements from `array` corresponding to the given indexes and returns |
||
5328 | * an array of the removed elements. Indexes may be specified as an array of |
||
5329 | * indexes or as individual arguments. |
||
5330 | * |
||
5331 | * **Note:** Unlike `_.at`, this method mutates `array`. |
||
5332 | * |
||
5333 | * @static |
||
5334 | * @memberOf _ |
||
5335 | * @category Array |
||
5336 | * @param {Array} array The array to modify. |
||
5337 | * @param {...(number|number[])} [indexes] The indexes of elements to remove, |
||
5338 | * specified as individual indexes or arrays of indexes. |
||
5339 | * @returns {Array} Returns the new array of removed elements. |
||
5340 | * @example |
||
5341 | * |
||
5342 | * var array = [5, 10, 15, 20]; |
||
5343 | * var evens = _.pullAt(array, 1, 3); |
||
5344 | * |
||
5345 | * console.log(array); |
||
5346 | * // => [5, 15] |
||
5347 | * |
||
5348 | * console.log(evens); |
||
5349 | * // => [10, 20] |
||
5350 | */ |
||
5351 | var pullAt = restParam(function(array, indexes) { |
||
5352 | indexes = baseFlatten(indexes); |
||
5353 | |||
5354 | var result = baseAt(array, indexes); |
||
5355 | basePullAt(array, indexes.sort(baseCompareAscending)); |
||
5356 | return result; |
||
5357 | }); |
||
5358 | |||
5359 | /** |
||
5360 | * Removes all elements from `array` that `predicate` returns truthy for |
||
5361 | * and returns an array of the removed elements. The predicate is bound to |
||
5362 | * `thisArg` and invoked with three arguments: (value, index, array). |
||
5363 | * |
||
5364 | * If a property name is provided for `predicate` the created `_.property` |
||
5365 | * style callback returns the property value of the given element. |
||
5366 | * |
||
5367 | * If a value is also provided for `thisArg` the created `_.matchesProperty` |
||
5368 | * style callback returns `true` for elements that have a matching property |
||
5369 | * value, else `false`. |
||
5370 | * |
||
5371 | * If an object is provided for `predicate` the created `_.matches` style |
||
5372 | * callback returns `true` for elements that have the properties of the given |
||
5373 | * object, else `false`. |
||
5374 | * |
||
5375 | * **Note:** Unlike `_.filter`, this method mutates `array`. |
||
5376 | * |
||
5377 | * @static |
||
5378 | * @memberOf _ |
||
5379 | * @category Array |
||
5380 | * @param {Array} array The array to modify. |
||
5381 | * @param {Function|Object|string} [predicate=_.identity] The function invoked |
||
5382 | * per iteration. |
||
5383 | * @param {*} [thisArg] The `this` binding of `predicate`. |
||
5384 | * @returns {Array} Returns the new array of removed elements. |
||
5385 | * @example |
||
5386 | * |
||
5387 | * var array = [1, 2, 3, 4]; |
||
5388 | * var evens = _.remove(array, function(n) { |
||
5389 | * return n % 2 == 0; |
||
5390 | * }); |
||
5391 | * |
||
5392 | * console.log(array); |
||
5393 | * // => [1, 3] |
||
5394 | * |
||
5395 | * console.log(evens); |
||
5396 | * // => [2, 4] |
||
5397 | */ |
||
5398 | function remove(array, predicate, thisArg) { |
||
5399 | var result = []; |
||
5400 | if (!(array && array.length)) { |
||
5401 | return result; |
||
5402 | } |
||
5403 | var index = -1, |
||
5404 | indexes = [], |
||
5405 | length = array.length; |
||
5406 | |||
5407 | predicate = getCallback(predicate, thisArg, 3); |
||
5408 | while (++index < length) { |
||
5409 | var value = array[index]; |
||
5410 | if (predicate(value, index, array)) { |
||
5411 | result.push(value); |
||
5412 | indexes.push(index); |
||
5413 | } |
||
5414 | } |
||
5415 | basePullAt(array, indexes); |
||
5416 | return result; |
||
5417 | } |
||
5418 | |||
5419 | /** |
||
5420 | * Gets all but the first element of `array`. |
||
5421 | * |
||
5422 | * @static |
||
5423 | * @memberOf _ |
||
5424 | * @alias tail |
||
5425 | * @category Array |
||
5426 | * @param {Array} array The array to query. |
||
5427 | * @returns {Array} Returns the slice of `array`. |
||
5428 | * @example |
||
5429 | * |
||
5430 | * _.rest([1, 2, 3]); |
||
5431 | * // => [2, 3] |
||
5432 | */ |
||
5433 | function rest(array) { |
||
5434 | return drop(array, 1); |
||
5435 | } |
||
5436 | |||
5437 | /** |
||
5438 | * Creates a slice of `array` from `start` up to, but not including, `end`. |
||
5439 | * |
||
5440 | * **Note:** This method is used instead of `Array#slice` to support node |
||
5441 | * lists in IE < 9 and to ensure dense arrays are returned. |
||
5442 | * |
||
5443 | * @static |
||
5444 | * @memberOf _ |
||
5445 | * @category Array |
||
5446 | * @param {Array} array The array to slice. |
||
5447 | * @param {number} [start=0] The start position. |
||
5448 | * @param {number} [end=array.length] The end position. |
||
5449 | * @returns {Array} Returns the slice of `array`. |
||
5450 | */ |
||
5451 | function slice(array, start, end) { |
||
5452 | var length = array ? array.length : 0; |
||
5453 | if (!length) { |
||
5454 | return []; |
||
5455 | } |
||
5456 | if (end && typeof end != 'number' && isIterateeCall(array, start, end)) { |
||
5457 | start = 0; |
||
5458 | end = length; |
||
5459 | } |
||
5460 | return baseSlice(array, start, end); |
||
5461 | } |
||
5462 | |||
5463 | /** |
||
5464 | * Uses a binary search to determine the lowest index at which `value` should |
||
5465 | * be inserted into `array` in order to maintain its sort order. If an iteratee |
||
5466 | * function is provided it's invoked for `value` and each element of `array` |
||
5467 | * to compute their sort ranking. The iteratee is bound to `thisArg` and |
||
5468 | * invoked with one argument; (value). |
||
5469 | * |
||
5470 | * If a property name is provided for `iteratee` the created `_.property` |
||
5471 | * style callback returns the property value of the given element. |
||
5472 | * |
||
5473 | * If a value is also provided for `thisArg` the created `_.matchesProperty` |
||
5474 | * style callback returns `true` for elements that have a matching property |
||
5475 | * value, else `false`. |
||
5476 | * |
||
5477 | * If an object is provided for `iteratee` the created `_.matches` style |
||
5478 | * callback returns `true` for elements that have the properties of the given |
||
5479 | * object, else `false`. |
||
5480 | * |
||
5481 | * @static |
||
5482 | * @memberOf _ |
||
5483 | * @category Array |
||
5484 | * @param {Array} array The sorted array to inspect. |
||
5485 | * @param {*} value The value to evaluate. |
||
5486 | * @param {Function|Object|string} [iteratee=_.identity] The function invoked |
||
5487 | * per iteration. |
||
5488 | * @param {*} [thisArg] The `this` binding of `iteratee`. |
||
5489 | * @returns {number} Returns the index at which `value` should be inserted |
||
5490 | * into `array`. |
||
5491 | * @example |
||
5492 | * |
||
5493 | * _.sortedIndex([30, 50], 40); |
||
5494 | * // => 1 |
||
5495 | * |
||
5496 | * _.sortedIndex([4, 4, 5, 5], 5); |
||
5497 | * // => 2 |
||
5498 | * |
||
5499 | * var dict = { 'data': { 'thirty': 30, 'forty': 40, 'fifty': 50 } }; |
||
5500 | * |
||
5501 | * // using an iteratee function |
||
5502 | * _.sortedIndex(['thirty', 'fifty'], 'forty', function(word) { |
||
5503 | * return this.data[word]; |
||
5504 | * }, dict); |
||
5505 | * // => 1 |
||
5506 | * |
||
5507 | * // using the `_.property` callback shorthand |
||
5508 | * _.sortedIndex([{ 'x': 30 }, { 'x': 50 }], { 'x': 40 }, 'x'); |
||
5509 | * // => 1 |
||
5510 | */ |
||
5511 | var sortedIndex = createSortedIndex(); |
||
5512 | |||
5513 | /** |
||
5514 | * This method is like `_.sortedIndex` except that it returns the highest |
||
5515 | * index at which `value` should be inserted into `array` in order to |
||
5516 | * maintain its sort order. |
||
5517 | * |
||
5518 | * @static |
||
5519 | * @memberOf _ |
||
5520 | * @category Array |
||
5521 | * @param {Array} array The sorted array to inspect. |
||
5522 | * @param {*} value The value to evaluate. |
||
5523 | * @param {Function|Object|string} [iteratee=_.identity] The function invoked |
||
5524 | * per iteration. |
||
5525 | * @param {*} [thisArg] The `this` binding of `iteratee`. |
||
5526 | * @returns {number} Returns the index at which `value` should be inserted |
||
5527 | * into `array`. |
||
5528 | * @example |
||
5529 | * |
||
5530 | * _.sortedLastIndex([4, 4, 5, 5], 5); |
||
5531 | * // => 4 |
||
5532 | */ |
||
5533 | var sortedLastIndex = createSortedIndex(true); |
||
5534 | |||
5535 | /** |
||
5536 | * Creates a slice of `array` with `n` elements taken from the beginning. |
||
5537 | * |
||
5538 | * @static |
||
5539 | * @memberOf _ |
||
5540 | * @category Array |
||
5541 | * @param {Array} array The array to query. |
||
5542 | * @param {number} [n=1] The number of elements to take. |
||
5543 | * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. |
||
5544 | * @returns {Array} Returns the slice of `array`. |
||
5545 | * @example |
||
5546 | * |
||
5547 | * _.take([1, 2, 3]); |
||
5548 | * // => [1] |
||
5549 | * |
||
5550 | * _.take([1, 2, 3], 2); |
||
5551 | * // => [1, 2] |
||
5552 | * |
||
5553 | * _.take([1, 2, 3], 5); |
||
5554 | * // => [1, 2, 3] |
||
5555 | * |
||
5556 | * _.take([1, 2, 3], 0); |
||
5557 | * // => [] |
||
5558 | */ |
||
5559 | function take(array, n, guard) { |
||
5560 | var length = array ? array.length : 0; |
||
5561 | if (!length) { |
||
5562 | return []; |
||
5563 | } |
||
5564 | if (guard ? isIterateeCall(array, n, guard) : n == null) { |
||
5565 | n = 1; |
||
5566 | } |
||
5567 | return baseSlice(array, 0, n < 0 ? 0 : n); |
||
5568 | } |
||
5569 | |||
5570 | /** |
||
5571 | * Creates a slice of `array` with `n` elements taken from the end. |
||
5572 | * |
||
5573 | * @static |
||
5574 | * @memberOf _ |
||
5575 | * @category Array |
||
5576 | * @param {Array} array The array to query. |
||
5577 | * @param {number} [n=1] The number of elements to take. |
||
5578 | * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. |
||
5579 | * @returns {Array} Returns the slice of `array`. |
||
5580 | * @example |
||
5581 | * |
||
5582 | * _.takeRight([1, 2, 3]); |
||
5583 | * // => [3] |
||
5584 | * |
||
5585 | * _.takeRight([1, 2, 3], 2); |
||
5586 | * // => [2, 3] |
||
5587 | * |
||
5588 | * _.takeRight([1, 2, 3], 5); |
||
5589 | * // => [1, 2, 3] |
||
5590 | * |
||
5591 | * _.takeRight([1, 2, 3], 0); |
||
5592 | * // => [] |
||
5593 | */ |
||
5594 | View Code Duplication | function takeRight(array, n, guard) { |
|
5595 | var length = array ? array.length : 0; |
||
5596 | if (!length) { |
||
5597 | return []; |
||
5598 | } |
||
5599 | if (guard ? isIterateeCall(array, n, guard) : n == null) { |
||
5600 | n = 1; |
||
5601 | } |
||
5602 | n = length - (+n || 0); |
||
5603 | return baseSlice(array, n < 0 ? 0 : n); |
||
5604 | } |
||
5605 | |||
5606 | /** |
||
5607 | * Creates a slice of `array` with elements taken from the end. Elements are |
||
5608 | * taken until `predicate` returns falsey. The predicate is bound to `thisArg` |
||
5609 | * and invoked with three arguments: (value, index, array). |
||
5610 | * |
||
5611 | * If a property name is provided for `predicate` the created `_.property` |
||
5612 | * style callback returns the property value of the given element. |
||
5613 | * |
||
5614 | * If a value is also provided for `thisArg` the created `_.matchesProperty` |
||
5615 | * style callback returns `true` for elements that have a matching property |
||
5616 | * value, else `false`. |
||
5617 | * |
||
5618 | * If an object is provided for `predicate` the created `_.matches` style |
||
5619 | * callback returns `true` for elements that have the properties of the given |
||
5620 | * object, else `false`. |
||
5621 | * |
||
5622 | * @static |
||
5623 | * @memberOf _ |
||
5624 | * @category Array |
||
5625 | * @param {Array} array The array to query. |
||
5626 | * @param {Function|Object|string} [predicate=_.identity] The function invoked |
||
5627 | * per iteration. |
||
5628 | * @param {*} [thisArg] The `this` binding of `predicate`. |
||
5629 | * @returns {Array} Returns the slice of `array`. |
||
5630 | * @example |
||
5631 | * |
||
5632 | * _.takeRightWhile([1, 2, 3], function(n) { |
||
5633 | * return n > 1; |
||
5634 | * }); |
||
5635 | * // => [2, 3] |
||
5636 | * |
||
5637 | * var users = [ |
||
5638 | * { 'user': 'barney', 'active': true }, |
||
5639 | * { 'user': 'fred', 'active': false }, |
||
5640 | * { 'user': 'pebbles', 'active': false } |
||
5641 | * ]; |
||
5642 | * |
||
5643 | * // using the `_.matches` callback shorthand |
||
5644 | * _.pluck(_.takeRightWhile(users, { 'user': 'pebbles', 'active': false }), 'user'); |
||
5645 | * // => ['pebbles'] |
||
5646 | * |
||
5647 | * // using the `_.matchesProperty` callback shorthand |
||
5648 | * _.pluck(_.takeRightWhile(users, 'active', false), 'user'); |
||
5649 | * // => ['fred', 'pebbles'] |
||
5650 | * |
||
5651 | * // using the `_.property` callback shorthand |
||
5652 | * _.pluck(_.takeRightWhile(users, 'active'), 'user'); |
||
5653 | * // => [] |
||
5654 | */ |
||
5655 | function takeRightWhile(array, predicate, thisArg) { |
||
5656 | return (array && array.length) |
||
5657 | ? baseWhile(array, getCallback(predicate, thisArg, 3), false, true) |
||
5658 | : []; |
||
5659 | } |
||
5660 | |||
5661 | /** |
||
5662 | * Creates a slice of `array` with elements taken from the beginning. Elements |
||
5663 | * are taken until `predicate` returns falsey. The predicate is bound to |
||
5664 | * `thisArg` and invoked with three arguments: (value, index, array). |
||
5665 | * |
||
5666 | * If a property name is provided for `predicate` the created `_.property` |
||
5667 | * style callback returns the property value of the given element. |
||
5668 | * |
||
5669 | * If a value is also provided for `thisArg` the created `_.matchesProperty` |
||
5670 | * style callback returns `true` for elements that have a matching property |
||
5671 | * value, else `false`. |
||
5672 | * |
||
5673 | * If an object is provided for `predicate` the created `_.matches` style |
||
5674 | * callback returns `true` for elements that have the properties of the given |
||
5675 | * object, else `false`. |
||
5676 | * |
||
5677 | * @static |
||
5678 | * @memberOf _ |
||
5679 | * @category Array |
||
5680 | * @param {Array} array The array to query. |
||
5681 | * @param {Function|Object|string} [predicate=_.identity] The function invoked |
||
5682 | * per iteration. |
||
5683 | * @param {*} [thisArg] The `this` binding of `predicate`. |
||
5684 | * @returns {Array} Returns the slice of `array`. |
||
5685 | * @example |
||
5686 | * |
||
5687 | * _.takeWhile([1, 2, 3], function(n) { |
||
5688 | * return n < 3; |
||
5689 | * }); |
||
5690 | * // => [1, 2] |
||
5691 | * |
||
5692 | * var users = [ |
||
5693 | * { 'user': 'barney', 'active': false }, |
||
5694 | * { 'user': 'fred', 'active': false}, |
||
5695 | * { 'user': 'pebbles', 'active': true } |
||
5696 | * ]; |
||
5697 | * |
||
5698 | * // using the `_.matches` callback shorthand |
||
5699 | * _.pluck(_.takeWhile(users, { 'user': 'barney', 'active': false }), 'user'); |
||
5700 | * // => ['barney'] |
||
5701 | * |
||
5702 | * // using the `_.matchesProperty` callback shorthand |
||
5703 | * _.pluck(_.takeWhile(users, 'active', false), 'user'); |
||
5704 | * // => ['barney', 'fred'] |
||
5705 | * |
||
5706 | * // using the `_.property` callback shorthand |
||
5707 | * _.pluck(_.takeWhile(users, 'active'), 'user'); |
||
5708 | * // => [] |
||
5709 | */ |
||
5710 | function takeWhile(array, predicate, thisArg) { |
||
5711 | return (array && array.length) |
||
5712 | ? baseWhile(array, getCallback(predicate, thisArg, 3)) |
||
5713 | : []; |
||
5714 | } |
||
5715 | |||
5716 | /** |
||
5717 | * Creates an array of unique values, in order, from all of the provided arrays |
||
5718 | * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) |
||
5719 | * for equality comparisons. |
||
5720 | * |
||
5721 | * @static |
||
5722 | * @memberOf _ |
||
5723 | * @category Array |
||
5724 | * @param {...Array} [arrays] The arrays to inspect. |
||
5725 | * @returns {Array} Returns the new array of combined values. |
||
5726 | * @example |
||
5727 | * |
||
5728 | * _.union([1, 2], [4, 2], [2, 1]); |
||
5729 | * // => [1, 2, 4] |
||
5730 | */ |
||
5731 | var union = restParam(function(arrays) { |
||
5732 | return baseUniq(baseFlatten(arrays, false, true)); |
||
5733 | }); |
||
5734 | |||
5735 | /** |
||
5736 | * Creates a duplicate-free version of an array, using |
||
5737 | * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) |
||
5738 | * for equality comparisons, in which only the first occurence of each element |
||
5739 | * is kept. Providing `true` for `isSorted` performs a faster search algorithm |
||
5740 | * for sorted arrays. If an iteratee function is provided it's invoked for |
||
5741 | * each element in the array to generate the criterion by which uniqueness |
||
5742 | * is computed. The `iteratee` is bound to `thisArg` and invoked with three |
||
5743 | * arguments: (value, index, array). |
||
5744 | * |
||
5745 | * If a property name is provided for `iteratee` the created `_.property` |
||
5746 | * style callback returns the property value of the given element. |
||
5747 | * |
||
5748 | * If a value is also provided for `thisArg` the created `_.matchesProperty` |
||
5749 | * style callback returns `true` for elements that have a matching property |
||
5750 | * value, else `false`. |
||
5751 | * |
||
5752 | * If an object is provided for `iteratee` the created `_.matches` style |
||
5753 | * callback returns `true` for elements that have the properties of the given |
||
5754 | * object, else `false`. |
||
5755 | * |
||
5756 | * @static |
||
5757 | * @memberOf _ |
||
5758 | * @alias unique |
||
5759 | * @category Array |
||
5760 | * @param {Array} array The array to inspect. |
||
5761 | * @param {boolean} [isSorted] Specify the array is sorted. |
||
5762 | * @param {Function|Object|string} [iteratee] The function invoked per iteration. |
||
5763 | * @param {*} [thisArg] The `this` binding of `iteratee`. |
||
5764 | * @returns {Array} Returns the new duplicate-value-free array. |
||
5765 | * @example |
||
5766 | * |
||
5767 | * _.uniq([2, 1, 2]); |
||
5768 | * // => [2, 1] |
||
5769 | * |
||
5770 | * // using `isSorted` |
||
5771 | * _.uniq([1, 1, 2], true); |
||
5772 | * // => [1, 2] |
||
5773 | * |
||
5774 | * // using an iteratee function |
||
5775 | * _.uniq([1, 2.5, 1.5, 2], function(n) { |
||
5776 | * return this.floor(n); |
||
5777 | * }, Math); |
||
5778 | * // => [1, 2.5] |
||
5779 | * |
||
5780 | * // using the `_.property` callback shorthand |
||
5781 | * _.uniq([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x'); |
||
5782 | * // => [{ 'x': 1 }, { 'x': 2 }] |
||
5783 | */ |
||
5784 | function uniq(array, isSorted, iteratee, thisArg) { |
||
5785 | var length = array ? array.length : 0; |
||
5786 | if (!length) { |
||
5787 | return []; |
||
5788 | } |
||
5789 | if (isSorted != null && typeof isSorted != 'boolean') { |
||
5790 | thisArg = iteratee; |
||
5791 | iteratee = isIterateeCall(array, isSorted, thisArg) ? undefined : isSorted; |
||
5792 | isSorted = false; |
||
5793 | } |
||
5794 | var callback = getCallback(); |
||
5795 | if (!(iteratee == null && callback === baseCallback)) { |
||
5796 | iteratee = callback(iteratee, thisArg, 3); |
||
5797 | } |
||
5798 | return (isSorted && getIndexOf() === baseIndexOf) |
||
5799 | ? sortedUniq(array, iteratee) |
||
5800 | : baseUniq(array, iteratee); |
||
5801 | } |
||
5802 | |||
5803 | /** |
||
5804 | * This method is like `_.zip` except that it accepts an array of grouped |
||
5805 | * elements and creates an array regrouping the elements to their pre-zip |
||
5806 | * configuration. |
||
5807 | * |
||
5808 | * @static |
||
5809 | * @memberOf _ |
||
5810 | * @category Array |
||
5811 | * @param {Array} array The array of grouped elements to process. |
||
5812 | * @returns {Array} Returns the new array of regrouped elements. |
||
5813 | * @example |
||
5814 | * |
||
5815 | * var zipped = _.zip(['fred', 'barney'], [30, 40], [true, false]); |
||
5816 | * // => [['fred', 30, true], ['barney', 40, false]] |
||
5817 | * |
||
5818 | * _.unzip(zipped); |
||
5819 | * // => [['fred', 'barney'], [30, 40], [true, false]] |
||
5820 | */ |
||
5821 | function unzip(array) { |
||
5822 | if (!(array && array.length)) { |
||
5823 | return []; |
||
5824 | } |
||
5825 | var index = -1, |
||
5826 | length = 0; |
||
5827 | |||
5828 | array = arrayFilter(array, function(group) { |
||
5829 | if (isArrayLike(group)) { |
||
5830 | length = nativeMax(group.length, length); |
||
5831 | return true; |
||
5832 | } |
||
5833 | }); |
||
5834 | var result = Array(length); |
||
5835 | while (++index < length) { |
||
5836 | result[index] = arrayMap(array, baseProperty(index)); |
||
5837 | } |
||
5838 | return result; |
||
5839 | } |
||
5840 | |||
5841 | /** |
||
5842 | * This method is like `_.unzip` except that it accepts an iteratee to specify |
||
5843 | * how regrouped values should be combined. The `iteratee` is bound to `thisArg` |
||
5844 | * and invoked with four arguments: (accumulator, value, index, group). |
||
5845 | * |
||
5846 | * @static |
||
5847 | * @memberOf _ |
||
5848 | * @category Array |
||
5849 | * @param {Array} array The array of grouped elements to process. |
||
5850 | * @param {Function} [iteratee] The function to combine regrouped values. |
||
5851 | * @param {*} [thisArg] The `this` binding of `iteratee`. |
||
5852 | * @returns {Array} Returns the new array of regrouped elements. |
||
5853 | * @example |
||
5854 | * |
||
5855 | * var zipped = _.zip([1, 2], [10, 20], [100, 200]); |
||
5856 | * // => [[1, 10, 100], [2, 20, 200]] |
||
5857 | * |
||
5858 | * _.unzipWith(zipped, _.add); |
||
5859 | * // => [3, 30, 300] |
||
5860 | */ |
||
5861 | function unzipWith(array, iteratee, thisArg) { |
||
5862 | var length = array ? array.length : 0; |
||
5863 | if (!length) { |
||
5864 | return []; |
||
5865 | } |
||
5866 | var result = unzip(array); |
||
5867 | if (iteratee == null) { |
||
5868 | return result; |
||
5869 | } |
||
5870 | iteratee = bindCallback(iteratee, thisArg, 4); |
||
5871 | return arrayMap(result, function(group) { |
||
5872 | return arrayReduce(group, iteratee, undefined, true); |
||
5873 | }); |
||
5874 | } |
||
5875 | |||
5876 | /** |
||
5877 | * Creates an array excluding all provided values using |
||
5878 | * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) |
||
5879 | * for equality comparisons. |
||
5880 | * |
||
5881 | * @static |
||
5882 | * @memberOf _ |
||
5883 | * @category Array |
||
5884 | * @param {Array} array The array to filter. |
||
5885 | * @param {...*} [values] The values to exclude. |
||
5886 | * @returns {Array} Returns the new array of filtered values. |
||
5887 | * @example |
||
5888 | * |
||
5889 | * _.without([1, 2, 1, 3], 1, 2); |
||
5890 | * // => [3] |
||
5891 | */ |
||
5892 | var without = restParam(function(array, values) { |
||
5893 | return isArrayLike(array) |
||
5894 | ? baseDifference(array, values) |
||
5895 | : []; |
||
5896 | }); |
||
5897 | |||
5898 | /** |
||
5899 | * Creates an array of unique values that is the [symmetric difference](https://en.wikipedia.org/wiki/Symmetric_difference) |
||
5900 | * of the provided arrays. |
||
5901 | * |
||
5902 | * @static |
||
5903 | * @memberOf _ |
||
5904 | * @category Array |
||
5905 | * @param {...Array} [arrays] The arrays to inspect. |
||
5906 | * @returns {Array} Returns the new array of values. |
||
5907 | * @example |
||
5908 | * |
||
5909 | * _.xor([1, 2], [4, 2]); |
||
5910 | * // => [1, 4] |
||
5911 | */ |
||
5912 | function xor() { |
||
5913 | var index = -1, |
||
5914 | length = arguments.length; |
||
5915 | |||
5916 | while (++index < length) { |
||
5917 | var array = arguments[index]; |
||
5918 | if (isArrayLike(array)) { |
||
5919 | var result = result |
||
5920 | ? arrayPush(baseDifference(result, array), baseDifference(array, result)) |
||
5921 | : array; |
||
5922 | } |
||
5923 | } |
||
5924 | return result ? baseUniq(result) : []; |
||
5925 | } |
||
5926 | |||
5927 | /** |
||
5928 | * Creates an array of grouped elements, the first of which contains the first |
||
5929 | * elements of the given arrays, the second of which contains the second elements |
||
5930 | * of the given arrays, and so on. |
||
5931 | * |
||
5932 | * @static |
||
5933 | * @memberOf _ |
||
5934 | * @category Array |
||
5935 | * @param {...Array} [arrays] The arrays to process. |
||
5936 | * @returns {Array} Returns the new array of grouped elements. |
||
5937 | * @example |
||
5938 | * |
||
5939 | * _.zip(['fred', 'barney'], [30, 40], [true, false]); |
||
5940 | * // => [['fred', 30, true], ['barney', 40, false]] |
||
5941 | */ |
||
5942 | var zip = restParam(unzip); |
||
5943 | |||
5944 | /** |
||
5945 | * The inverse of `_.pairs`; this method returns an object composed from arrays |
||
5946 | * of property names and values. Provide either a single two dimensional array, |
||
5947 | * e.g. `[[key1, value1], [key2, value2]]` or two arrays, one of property names |
||
5948 | * and one of corresponding values. |
||
5949 | * |
||
5950 | * @static |
||
5951 | * @memberOf _ |
||
5952 | * @alias object |
||
5953 | * @category Array |
||
5954 | * @param {Array} props The property names. |
||
5955 | * @param {Array} [values=[]] The property values. |
||
5956 | * @returns {Object} Returns the new object. |
||
5957 | * @example |
||
5958 | * |
||
5959 | * _.zipObject([['fred', 30], ['barney', 40]]); |
||
5960 | * // => { 'fred': 30, 'barney': 40 } |
||
5961 | * |
||
5962 | * _.zipObject(['fred', 'barney'], [30, 40]); |
||
5963 | * // => { 'fred': 30, 'barney': 40 } |
||
5964 | */ |
||
5965 | function zipObject(props, values) { |
||
5966 | var index = -1, |
||
5967 | length = props ? props.length : 0, |
||
5968 | result = {}; |
||
5969 | |||
5970 | if (length && !values && !isArray(props[0])) { |
||
5971 | values = []; |
||
5972 | } |
||
5973 | while (++index < length) { |
||
5974 | var key = props[index]; |
||
5975 | if (values) { |
||
5976 | result[key] = values[index]; |
||
5977 | } else if (key) { |
||
5978 | result[key[0]] = key[1]; |
||
5979 | } |
||
5980 | } |
||
5981 | return result; |
||
5982 | } |
||
5983 | |||
5984 | /** |
||
5985 | * This method is like `_.zip` except that it accepts an iteratee to specify |
||
5986 | * how grouped values should be combined. The `iteratee` is bound to `thisArg` |
||
5987 | * and invoked with four arguments: (accumulator, value, index, group). |
||
5988 | * |
||
5989 | * @static |
||
5990 | * @memberOf _ |
||
5991 | * @category Array |
||
5992 | * @param {...Array} [arrays] The arrays to process. |
||
5993 | * @param {Function} [iteratee] The function to combine grouped values. |
||
5994 | * @param {*} [thisArg] The `this` binding of `iteratee`. |
||
5995 | * @returns {Array} Returns the new array of grouped elements. |
||
5996 | * @example |
||
5997 | * |
||
5998 | * _.zipWith([1, 2], [10, 20], [100, 200], _.add); |
||
5999 | * // => [111, 222] |
||
6000 | */ |
||
6001 | var zipWith = restParam(function(arrays) { |
||
6002 | var length = arrays.length, |
||
6003 | iteratee = length > 2 ? arrays[length - 2] : undefined, |
||
6004 | thisArg = length > 1 ? arrays[length - 1] : undefined; |
||
6005 | |||
6006 | if (length > 2 && typeof iteratee == 'function') { |
||
6007 | length -= 2; |
||
6008 | } else { |
||
6009 | iteratee = (length > 1 && typeof thisArg == 'function') ? (--length, thisArg) : undefined; |
||
6010 | thisArg = undefined; |
||
6011 | } |
||
6012 | arrays.length = length; |
||
6013 | return unzipWith(arrays, iteratee, thisArg); |
||
6014 | }); |
||
6015 | |||
6016 | /*------------------------------------------------------------------------*/ |
||
6017 | |||
6018 | /** |
||
6019 | * Creates a `lodash` object that wraps `value` with explicit method |
||
6020 | * chaining enabled. |
||
6021 | * |
||
6022 | * @static |
||
6023 | * @memberOf _ |
||
6024 | * @category Chain |
||
6025 | * @param {*} value The value to wrap. |
||
6026 | * @returns {Object} Returns the new `lodash` wrapper instance. |
||
6027 | * @example |
||
6028 | * |
||
6029 | * var users = [ |
||
6030 | * { 'user': 'barney', 'age': 36 }, |
||
6031 | * { 'user': 'fred', 'age': 40 }, |
||
6032 | * { 'user': 'pebbles', 'age': 1 } |
||
6033 | * ]; |
||
6034 | * |
||
6035 | * var youngest = _.chain(users) |
||
6036 | * .sortBy('age') |
||
6037 | * .map(function(chr) { |
||
6038 | * return chr.user + ' is ' + chr.age; |
||
6039 | * }) |
||
6040 | * .first() |
||
6041 | * .value(); |
||
6042 | * // => 'pebbles is 1' |
||
6043 | */ |
||
6044 | function chain(value) { |
||
6045 | var result = lodash(value); |
||
6046 | result.__chain__ = true; |
||
6047 | return result; |
||
6048 | } |
||
6049 | |||
6050 | /** |
||
6051 | * This method invokes `interceptor` and returns `value`. The interceptor is |
||
6052 | * bound to `thisArg` and invoked with one argument; (value). The purpose of |
||
6053 | * this method is to "tap into" a method chain in order to perform operations |
||
6054 | * on intermediate results within the chain. |
||
6055 | * |
||
6056 | * @static |
||
6057 | * @memberOf _ |
||
6058 | * @category Chain |
||
6059 | * @param {*} value The value to provide to `interceptor`. |
||
6060 | * @param {Function} interceptor The function to invoke. |
||
6061 | * @param {*} [thisArg] The `this` binding of `interceptor`. |
||
6062 | * @returns {*} Returns `value`. |
||
6063 | * @example |
||
6064 | * |
||
6065 | * _([1, 2, 3]) |
||
6066 | * .tap(function(array) { |
||
6067 | * array.pop(); |
||
6068 | * }) |
||
6069 | * .reverse() |
||
6070 | * .value(); |
||
6071 | * // => [2, 1] |
||
6072 | */ |
||
6073 | function tap(value, interceptor, thisArg) { |
||
6074 | interceptor.call(thisArg, value); |
||
6075 | return value; |
||
6076 | } |
||
6077 | |||
6078 | /** |
||
6079 | * This method is like `_.tap` except that it returns the result of `interceptor`. |
||
6080 | * |
||
6081 | * @static |
||
6082 | * @memberOf _ |
||
6083 | * @category Chain |
||
6084 | * @param {*} value The value to provide to `interceptor`. |
||
6085 | * @param {Function} interceptor The function to invoke. |
||
6086 | * @param {*} [thisArg] The `this` binding of `interceptor`. |
||
6087 | * @returns {*} Returns the result of `interceptor`. |
||
6088 | * @example |
||
6089 | * |
||
6090 | * _(' abc ') |
||
6091 | * .chain() |
||
6092 | * .trim() |
||
6093 | * .thru(function(value) { |
||
6094 | * return [value]; |
||
6095 | * }) |
||
6096 | * .value(); |
||
6097 | * // => ['abc'] |
||
6098 | */ |
||
6099 | function thru(value, interceptor, thisArg) { |
||
6100 | return interceptor.call(thisArg, value); |
||
6101 | } |
||
6102 | |||
6103 | /** |
||
6104 | * Enables explicit method chaining on the wrapper object. |
||
6105 | * |
||
6106 | * @name chain |
||
6107 | * @memberOf _ |
||
6108 | * @category Chain |
||
6109 | * @returns {Object} Returns the new `lodash` wrapper instance. |
||
6110 | * @example |
||
6111 | * |
||
6112 | * var users = [ |
||
6113 | * { 'user': 'barney', 'age': 36 }, |
||
6114 | * { 'user': 'fred', 'age': 40 } |
||
6115 | * ]; |
||
6116 | * |
||
6117 | * // without explicit chaining |
||
6118 | * _(users).first(); |
||
6119 | * // => { 'user': 'barney', 'age': 36 } |
||
6120 | * |
||
6121 | * // with explicit chaining |
||
6122 | * _(users).chain() |
||
6123 | * .first() |
||
6124 | * .pick('user') |
||
6125 | * .value(); |
||
6126 | * // => { 'user': 'barney' } |
||
6127 | */ |
||
6128 | function wrapperChain() { |
||
6129 | return chain(this); |
||
6130 | } |
||
6131 | |||
6132 | /** |
||
6133 | * Executes the chained sequence and returns the wrapped result. |
||
6134 | * |
||
6135 | * @name commit |
||
6136 | * @memberOf _ |
||
6137 | * @category Chain |
||
6138 | * @returns {Object} Returns the new `lodash` wrapper instance. |
||
6139 | * @example |
||
6140 | * |
||
6141 | * var array = [1, 2]; |
||
6142 | * var wrapped = _(array).push(3); |
||
6143 | * |
||
6144 | * console.log(array); |
||
6145 | * // => [1, 2] |
||
6146 | * |
||
6147 | * wrapped = wrapped.commit(); |
||
6148 | * console.log(array); |
||
6149 | * // => [1, 2, 3] |
||
6150 | * |
||
6151 | * wrapped.last(); |
||
6152 | * // => 3 |
||
6153 | * |
||
6154 | * console.log(array); |
||
6155 | * // => [1, 2, 3] |
||
6156 | */ |
||
6157 | function wrapperCommit() { |
||
6158 | return new LodashWrapper(this.value(), this.__chain__); |
||
6159 | } |
||
6160 | |||
6161 | /** |
||
6162 | * Creates a new array joining a wrapped array with any additional arrays |
||
6163 | * and/or values. |
||
6164 | * |
||
6165 | * @name concat |
||
6166 | * @memberOf _ |
||
6167 | * @category Chain |
||
6168 | * @param {...*} [values] The values to concatenate. |
||
6169 | * @returns {Array} Returns the new concatenated array. |
||
6170 | * @example |
||
6171 | * |
||
6172 | * var array = [1]; |
||
6173 | * var wrapped = _(array).concat(2, [3], [[4]]); |
||
6174 | * |
||
6175 | * console.log(wrapped.value()); |
||
6176 | * // => [1, 2, 3, [4]] |
||
6177 | * |
||
6178 | * console.log(array); |
||
6179 | * // => [1] |
||
6180 | */ |
||
6181 | var wrapperConcat = restParam(function(values) { |
||
6182 | values = baseFlatten(values); |
||
6183 | return this.thru(function(array) { |
||
6184 | return arrayConcat(isArray(array) ? array : [toObject(array)], values); |
||
6185 | }); |
||
6186 | }); |
||
6187 | |||
6188 | /** |
||
6189 | * Creates a clone of the chained sequence planting `value` as the wrapped value. |
||
6190 | * |
||
6191 | * @name plant |
||
6192 | * @memberOf _ |
||
6193 | * @category Chain |
||
6194 | * @returns {Object} Returns the new `lodash` wrapper instance. |
||
6195 | * @example |
||
6196 | * |
||
6197 | * var array = [1, 2]; |
||
6198 | * var wrapped = _(array).map(function(value) { |
||
6199 | * return Math.pow(value, 2); |
||
6200 | * }); |
||
6201 | * |
||
6202 | * var other = [3, 4]; |
||
6203 | * var otherWrapped = wrapped.plant(other); |
||
6204 | * |
||
6205 | * otherWrapped.value(); |
||
6206 | * // => [9, 16] |
||
6207 | * |
||
6208 | * wrapped.value(); |
||
6209 | * // => [1, 4] |
||
6210 | */ |
||
6211 | function wrapperPlant(value) { |
||
6212 | var result, |
||
6213 | parent = this; |
||
6214 | |||
6215 | while (parent instanceof baseLodash) { |
||
6216 | var clone = wrapperClone(parent); |
||
6217 | if (result) { |
||
6218 | previous.__wrapped__ = clone; |
||
6219 | } else { |
||
6220 | result = clone; |
||
6221 | } |
||
6222 | var previous = clone; |
||
6223 | parent = parent.__wrapped__; |
||
6224 | } |
||
6225 | previous.__wrapped__ = value; |
||
6226 | return result; |
||
6227 | } |
||
6228 | |||
6229 | /** |
||
6230 | * Reverses the wrapped array so the first element becomes the last, the |
||
6231 | * second element becomes the second to last, and so on. |
||
6232 | * |
||
6233 | * **Note:** This method mutates the wrapped array. |
||
6234 | * |
||
6235 | * @name reverse |
||
6236 | * @memberOf _ |
||
6237 | * @category Chain |
||
6238 | * @returns {Object} Returns the new reversed `lodash` wrapper instance. |
||
6239 | * @example |
||
6240 | * |
||
6241 | * var array = [1, 2, 3]; |
||
6242 | * |
||
6243 | * _(array).reverse().value() |
||
6244 | * // => [3, 2, 1] |
||
6245 | * |
||
6246 | * console.log(array); |
||
6247 | * // => [3, 2, 1] |
||
6248 | */ |
||
6249 | function wrapperReverse() { |
||
6250 | var value = this.__wrapped__; |
||
6251 | |||
6252 | var interceptor = function(value) { |
||
6253 | return value.reverse(); |
||
6254 | }; |
||
6255 | if (value instanceof LazyWrapper) { |
||
6256 | var wrapped = value; |
||
6257 | if (this.__actions__.length) { |
||
6258 | wrapped = new LazyWrapper(this); |
||
6259 | } |
||
6260 | wrapped = wrapped.reverse(); |
||
6261 | wrapped.__actions__.push({ 'func': thru, 'args': [interceptor], 'thisArg': undefined }); |
||
6262 | return new LodashWrapper(wrapped, this.__chain__); |
||
6263 | } |
||
6264 | return this.thru(interceptor); |
||
6265 | } |
||
6266 | |||
6267 | /** |
||
6268 | * Produces the result of coercing the unwrapped value to a string. |
||
6269 | * |
||
6270 | * @name toString |
||
6271 | * @memberOf _ |
||
6272 | * @category Chain |
||
6273 | * @returns {string} Returns the coerced string value. |
||
6274 | * @example |
||
6275 | * |
||
6276 | * _([1, 2, 3]).toString(); |
||
6277 | * // => '1,2,3' |
||
6278 | */ |
||
6279 | function wrapperToString() { |
||
6280 | return (this.value() + ''); |
||
6281 | } |
||
6282 | |||
6283 | /** |
||
6284 | * Executes the chained sequence to extract the unwrapped value. |
||
6285 | * |
||
6286 | * @name value |
||
6287 | * @memberOf _ |
||
6288 | * @alias run, toJSON, valueOf |
||
6289 | * @category Chain |
||
6290 | * @returns {*} Returns the resolved unwrapped value. |
||
6291 | * @example |
||
6292 | * |
||
6293 | * _([1, 2, 3]).value(); |
||
6294 | * // => [1, 2, 3] |
||
6295 | */ |
||
6296 | function wrapperValue() { |
||
6297 | return baseWrapperValue(this.__wrapped__, this.__actions__); |
||
6298 | } |
||
6299 | |||
6300 | /*------------------------------------------------------------------------*/ |
||
6301 | |||
6302 | /** |
||
6303 | * Creates an array of elements corresponding to the given keys, or indexes, |
||
6304 | * of `collection`. Keys may be specified as individual arguments or as arrays |
||
6305 | * of keys. |
||
6306 | * |
||
6307 | * @static |
||
6308 | * @memberOf _ |
||
6309 | * @category Collection |
||
6310 | * @param {Array|Object|string} collection The collection to iterate over. |
||
6311 | * @param {...(number|number[]|string|string[])} [props] The property names |
||
6312 | * or indexes of elements to pick, specified individually or in arrays. |
||
6313 | * @returns {Array} Returns the new array of picked elements. |
||
6314 | * @example |
||
6315 | * |
||
6316 | * _.at(['a', 'b', 'c'], [0, 2]); |
||
6317 | * // => ['a', 'c'] |
||
6318 | * |
||
6319 | * _.at(['barney', 'fred', 'pebbles'], 0, 2); |
||
6320 | * // => ['barney', 'pebbles'] |
||
6321 | */ |
||
6322 | var at = restParam(function(collection, props) { |
||
6323 | if (isArrayLike(collection)) { |
||
6324 | collection = toIterable(collection); |
||
6325 | } |
||
6326 | return baseAt(collection, baseFlatten(props)); |
||
6327 | }); |
||
6328 | |||
6329 | /** |
||
6330 | * Creates an object composed of keys generated from the results of running |
||
6331 | * each element of `collection` through `iteratee`. The corresponding value |
||
6332 | * of each key is the number of times the key was returned by `iteratee`. |
||
6333 | * The `iteratee` is bound to `thisArg` and invoked with three arguments: |
||
6334 | * (value, index|key, collection). |
||
6335 | * |
||
6336 | * If a property name is provided for `iteratee` the created `_.property` |
||
6337 | * style callback returns the property value of the given element. |
||
6338 | * |
||
6339 | * If a value is also provided for `thisArg` the created `_.matchesProperty` |
||
6340 | * style callback returns `true` for elements that have a matching property |
||
6341 | * value, else `false`. |
||
6342 | * |
||
6343 | * If an object is provided for `iteratee` the created `_.matches` style |
||
6344 | * callback returns `true` for elements that have the properties of the given |
||
6345 | * object, else `false`. |
||
6346 | * |
||
6347 | * @static |
||
6348 | * @memberOf _ |
||
6349 | * @category Collection |
||
6350 | * @param {Array|Object|string} collection The collection to iterate over. |
||
6351 | * @param {Function|Object|string} [iteratee=_.identity] The function invoked |
||
6352 | * per iteration. |
||
6353 | * @param {*} [thisArg] The `this` binding of `iteratee`. |
||
6354 | * @returns {Object} Returns the composed aggregate object. |
||
6355 | * @example |
||
6356 | * |
||
6357 | * _.countBy([4.3, 6.1, 6.4], function(n) { |
||
6358 | * return Math.floor(n); |
||
6359 | * }); |
||
6360 | * // => { '4': 1, '6': 2 } |
||
6361 | * |
||
6362 | * _.countBy([4.3, 6.1, 6.4], function(n) { |
||
6363 | * return this.floor(n); |
||
6364 | * }, Math); |
||
6365 | * // => { '4': 1, '6': 2 } |
||
6366 | * |
||
6367 | * _.countBy(['one', 'two', 'three'], 'length'); |
||
6368 | * // => { '3': 2, '5': 1 } |
||
6369 | */ |
||
6370 | var countBy = createAggregator(function(result, value, key) { |
||
6371 | hasOwnProperty.call(result, key) ? ++result[key] : (result[key] = 1); |
||
6372 | }); |
||
6373 | |||
6374 | /** |
||
6375 | * Checks if `predicate` returns truthy for **all** elements of `collection`. |
||
6376 | * The predicate is bound to `thisArg` and invoked with three arguments: |
||
6377 | * (value, index|key, collection). |
||
6378 | * |
||
6379 | * If a property name is provided for `predicate` the created `_.property` |
||
6380 | * style callback returns the property value of the given element. |
||
6381 | * |
||
6382 | * If a value is also provided for `thisArg` the created `_.matchesProperty` |
||
6383 | * style callback returns `true` for elements that have a matching property |
||
6384 | * value, else `false`. |
||
6385 | * |
||
6386 | * If an object is provided for `predicate` the created `_.matches` style |
||
6387 | * callback returns `true` for elements that have the properties of the given |
||
6388 | * object, else `false`. |
||
6389 | * |
||
6390 | * @static |
||
6391 | * @memberOf _ |
||
6392 | * @alias all |
||
6393 | * @category Collection |
||
6394 | * @param {Array|Object|string} collection The collection to iterate over. |
||
6395 | * @param {Function|Object|string} [predicate=_.identity] The function invoked |
||
6396 | * per iteration. |
||
6397 | * @param {*} [thisArg] The `this` binding of `predicate`. |
||
6398 | * @returns {boolean} Returns `true` if all elements pass the predicate check, |
||
6399 | * else `false`. |
||
6400 | * @example |
||
6401 | * |
||
6402 | * _.every([true, 1, null, 'yes'], Boolean); |
||
6403 | * // => false |
||
6404 | * |
||
6405 | * var users = [ |
||
6406 | * { 'user': 'barney', 'active': false }, |
||
6407 | * { 'user': 'fred', 'active': false } |
||
6408 | * ]; |
||
6409 | * |
||
6410 | * // using the `_.matches` callback shorthand |
||
6411 | * _.every(users, { 'user': 'barney', 'active': false }); |
||
6412 | * // => false |
||
6413 | * |
||
6414 | * // using the `_.matchesProperty` callback shorthand |
||
6415 | * _.every(users, 'active', false); |
||
6416 | * // => true |
||
6417 | * |
||
6418 | * // using the `_.property` callback shorthand |
||
6419 | * _.every(users, 'active'); |
||
6420 | * // => false |
||
6421 | */ |
||
6422 | function every(collection, predicate, thisArg) { |
||
6423 | var func = isArray(collection) ? arrayEvery : baseEvery; |
||
6424 | if (thisArg && isIterateeCall(collection, predicate, thisArg)) { |
||
6425 | predicate = undefined; |
||
6426 | } |
||
6427 | if (typeof predicate != 'function' || thisArg !== undefined) { |
||
6428 | predicate = getCallback(predicate, thisArg, 3); |
||
6429 | } |
||
6430 | return func(collection, predicate); |
||
6431 | } |
||
6432 | |||
6433 | /** |
||
6434 | * Iterates over elements of `collection`, returning an array of all elements |
||
6435 | * `predicate` returns truthy for. The predicate is bound to `thisArg` and |
||
6436 | * invoked with three arguments: (value, index|key, collection). |
||
6437 | * |
||
6438 | * If a property name is provided for `predicate` the created `_.property` |
||
6439 | * style callback returns the property value of the given element. |
||
6440 | * |
||
6441 | * If a value is also provided for `thisArg` the created `_.matchesProperty` |
||
6442 | * style callback returns `true` for elements that have a matching property |
||
6443 | * value, else `false`. |
||
6444 | * |
||
6445 | * If an object is provided for `predicate` the created `_.matches` style |
||
6446 | * callback returns `true` for elements that have the properties of the given |
||
6447 | * object, else `false`. |
||
6448 | * |
||
6449 | * @static |
||
6450 | * @memberOf _ |
||
6451 | * @alias select |
||
6452 | * @category Collection |
||
6453 | * @param {Array|Object|string} collection The collection to iterate over. |
||
6454 | * @param {Function|Object|string} [predicate=_.identity] The function invoked |
||
6455 | * per iteration. |
||
6456 | * @param {*} [thisArg] The `this` binding of `predicate`. |
||
6457 | * @returns {Array} Returns the new filtered array. |
||
6458 | * @example |
||
6459 | * |
||
6460 | * _.filter([4, 5, 6], function(n) { |
||
6461 | * return n % 2 == 0; |
||
6462 | * }); |
||
6463 | * // => [4, 6] |
||
6464 | * |
||
6465 | * var users = [ |
||
6466 | * { 'user': 'barney', 'age': 36, 'active': true }, |
||
6467 | * { 'user': 'fred', 'age': 40, 'active': false } |
||
6468 | * ]; |
||
6469 | * |
||
6470 | * // using the `_.matches` callback shorthand |
||
6471 | * _.pluck(_.filter(users, { 'age': 36, 'active': true }), 'user'); |
||
6472 | * // => ['barney'] |
||
6473 | * |
||
6474 | * // using the `_.matchesProperty` callback shorthand |
||
6475 | * _.pluck(_.filter(users, 'active', false), 'user'); |
||
6476 | * // => ['fred'] |
||
6477 | * |
||
6478 | * // using the `_.property` callback shorthand |
||
6479 | * _.pluck(_.filter(users, 'active'), 'user'); |
||
6480 | * // => ['barney'] |
||
6481 | */ |
||
6482 | function filter(collection, predicate, thisArg) { |
||
6483 | var func = isArray(collection) ? arrayFilter : baseFilter; |
||
6484 | predicate = getCallback(predicate, thisArg, 3); |
||
6485 | return func(collection, predicate); |
||
6486 | } |
||
6487 | |||
6488 | /** |
||
6489 | * Iterates over elements of `collection`, returning the first element |
||
6490 | * `predicate` returns truthy for. The predicate is bound to `thisArg` and |
||
6491 | * invoked with three arguments: (value, index|key, collection). |
||
6492 | * |
||
6493 | * If a property name is provided for `predicate` the created `_.property` |
||
6494 | * style callback returns the property value of the given element. |
||
6495 | * |
||
6496 | * If a value is also provided for `thisArg` the created `_.matchesProperty` |
||
6497 | * style callback returns `true` for elements that have a matching property |
||
6498 | * value, else `false`. |
||
6499 | * |
||
6500 | * If an object is provided for `predicate` the created `_.matches` style |
||
6501 | * callback returns `true` for elements that have the properties of the given |
||
6502 | * object, else `false`. |
||
6503 | * |
||
6504 | * @static |
||
6505 | * @memberOf _ |
||
6506 | * @alias detect |
||
6507 | * @category Collection |
||
6508 | * @param {Array|Object|string} collection The collection to search. |
||
6509 | * @param {Function|Object|string} [predicate=_.identity] The function invoked |
||
6510 | * per iteration. |
||
6511 | * @param {*} [thisArg] The `this` binding of `predicate`. |
||
6512 | * @returns {*} Returns the matched element, else `undefined`. |
||
6513 | * @example |
||
6514 | * |
||
6515 | * var users = [ |
||
6516 | * { 'user': 'barney', 'age': 36, 'active': true }, |
||
6517 | * { 'user': 'fred', 'age': 40, 'active': false }, |
||
6518 | * { 'user': 'pebbles', 'age': 1, 'active': true } |
||
6519 | * ]; |
||
6520 | * |
||
6521 | * _.result(_.find(users, function(chr) { |
||
6522 | * return chr.age < 40; |
||
6523 | * }), 'user'); |
||
6524 | * // => 'barney' |
||
6525 | * |
||
6526 | * // using the `_.matches` callback shorthand |
||
6527 | * _.result(_.find(users, { 'age': 1, 'active': true }), 'user'); |
||
6528 | * // => 'pebbles' |
||
6529 | * |
||
6530 | * // using the `_.matchesProperty` callback shorthand |
||
6531 | * _.result(_.find(users, 'active', false), 'user'); |
||
6532 | * // => 'fred' |
||
6533 | * |
||
6534 | * // using the `_.property` callback shorthand |
||
6535 | * _.result(_.find(users, 'active'), 'user'); |
||
6536 | * // => 'barney' |
||
6537 | */ |
||
6538 | var find = createFind(baseEach); |
||
6539 | |||
6540 | /** |
||
6541 | * This method is like `_.find` except that it iterates over elements of |
||
6542 | * `collection` from right to left. |
||
6543 | * |
||
6544 | * @static |
||
6545 | * @memberOf _ |
||
6546 | * @category Collection |
||
6547 | * @param {Array|Object|string} collection The collection to search. |
||
6548 | * @param {Function|Object|string} [predicate=_.identity] The function invoked |
||
6549 | * per iteration. |
||
6550 | * @param {*} [thisArg] The `this` binding of `predicate`. |
||
6551 | * @returns {*} Returns the matched element, else `undefined`. |
||
6552 | * @example |
||
6553 | * |
||
6554 | * _.findLast([1, 2, 3, 4], function(n) { |
||
6555 | * return n % 2 == 1; |
||
6556 | * }); |
||
6557 | * // => 3 |
||
6558 | */ |
||
6559 | var findLast = createFind(baseEachRight, true); |
||
6560 | |||
6561 | /** |
||
6562 | * Performs a deep comparison between each element in `collection` and the |
||
6563 | * source object, returning the first element that has equivalent property |
||
6564 | * values. |
||
6565 | * |
||
6566 | * **Note:** This method supports comparing arrays, booleans, `Date` objects, |
||
6567 | * numbers, `Object` objects, regexes, and strings. Objects are compared by |
||
6568 | * their own, not inherited, enumerable properties. For comparing a single |
||
6569 | * own or inherited property value see `_.matchesProperty`. |
||
6570 | * |
||
6571 | * @static |
||
6572 | * @memberOf _ |
||
6573 | * @category Collection |
||
6574 | * @param {Array|Object|string} collection The collection to search. |
||
6575 | * @param {Object} source The object of property values to match. |
||
6576 | * @returns {*} Returns the matched element, else `undefined`. |
||
6577 | * @example |
||
6578 | * |
||
6579 | * var users = [ |
||
6580 | * { 'user': 'barney', 'age': 36, 'active': true }, |
||
6581 | * { 'user': 'fred', 'age': 40, 'active': false } |
||
6582 | * ]; |
||
6583 | * |
||
6584 | * _.result(_.findWhere(users, { 'age': 36, 'active': true }), 'user'); |
||
6585 | * // => 'barney' |
||
6586 | * |
||
6587 | * _.result(_.findWhere(users, { 'age': 40, 'active': false }), 'user'); |
||
6588 | * // => 'fred' |
||
6589 | */ |
||
6590 | function findWhere(collection, source) { |
||
6591 | return find(collection, baseMatches(source)); |
||
6592 | } |
||
6593 | |||
6594 | /** |
||
6595 | * Iterates over elements of `collection` invoking `iteratee` for each element. |
||
6596 | * The `iteratee` is bound to `thisArg` and invoked with three arguments: |
||
6597 | * (value, index|key, collection). Iteratee functions may exit iteration early |
||
6598 | * by explicitly returning `false`. |
||
6599 | * |
||
6600 | * **Note:** As with other "Collections" methods, objects with a "length" property |
||
6601 | * are iterated like arrays. To avoid this behavior `_.forIn` or `_.forOwn` |
||
6602 | * may be used for object iteration. |
||
6603 | * |
||
6604 | * @static |
||
6605 | * @memberOf _ |
||
6606 | * @alias each |
||
6607 | * @category Collection |
||
6608 | * @param {Array|Object|string} collection The collection to iterate over. |
||
6609 | * @param {Function} [iteratee=_.identity] The function invoked per iteration. |
||
6610 | * @param {*} [thisArg] The `this` binding of `iteratee`. |
||
6611 | * @returns {Array|Object|string} Returns `collection`. |
||
6612 | * @example |
||
6613 | * |
||
6614 | * _([1, 2]).forEach(function(n) { |
||
6615 | * console.log(n); |
||
6616 | * }).value(); |
||
6617 | * // => logs each value from left to right and returns the array |
||
6618 | * |
||
6619 | * _.forEach({ 'a': 1, 'b': 2 }, function(n, key) { |
||
6620 | * console.log(n, key); |
||
6621 | * }); |
||
6622 | * // => logs each value-key pair and returns the object (iteration order is not guaranteed) |
||
6623 | */ |
||
6624 | var forEach = createForEach(arrayEach, baseEach); |
||
6625 | |||
6626 | /** |
||
6627 | * This method is like `_.forEach` except that it iterates over elements of |
||
6628 | * `collection` from right to left. |
||
6629 | * |
||
6630 | * @static |
||
6631 | * @memberOf _ |
||
6632 | * @alias eachRight |
||
6633 | * @category Collection |
||
6634 | * @param {Array|Object|string} collection The collection to iterate over. |
||
6635 | * @param {Function} [iteratee=_.identity] The function invoked per iteration. |
||
6636 | * @param {*} [thisArg] The `this` binding of `iteratee`. |
||
6637 | * @returns {Array|Object|string} Returns `collection`. |
||
6638 | * @example |
||
6639 | * |
||
6640 | * _([1, 2]).forEachRight(function(n) { |
||
6641 | * console.log(n); |
||
6642 | * }).value(); |
||
6643 | * // => logs each value from right to left and returns the array |
||
6644 | */ |
||
6645 | var forEachRight = createForEach(arrayEachRight, baseEachRight); |
||
6646 | |||
6647 | /** |
||
6648 | * Creates an object composed of keys generated from the results of running |
||
6649 | * each element of `collection` through `iteratee`. The corresponding value |
||
6650 | * of each key is an array of the elements responsible for generating the key. |
||
6651 | * The `iteratee` is bound to `thisArg` and invoked with three arguments: |
||
6652 | * (value, index|key, collection). |
||
6653 | * |
||
6654 | * If a property name is provided for `iteratee` the created `_.property` |
||
6655 | * style callback returns the property value of the given element. |
||
6656 | * |
||
6657 | * If a value is also provided for `thisArg` the created `_.matchesProperty` |
||
6658 | * style callback returns `true` for elements that have a matching property |
||
6659 | * value, else `false`. |
||
6660 | * |
||
6661 | * If an object is provided for `iteratee` the created `_.matches` style |
||
6662 | * callback returns `true` for elements that have the properties of the given |
||
6663 | * object, else `false`. |
||
6664 | * |
||
6665 | * @static |
||
6666 | * @memberOf _ |
||
6667 | * @category Collection |
||
6668 | * @param {Array|Object|string} collection The collection to iterate over. |
||
6669 | * @param {Function|Object|string} [iteratee=_.identity] The function invoked |
||
6670 | * per iteration. |
||
6671 | * @param {*} [thisArg] The `this` binding of `iteratee`. |
||
6672 | * @returns {Object} Returns the composed aggregate object. |
||
6673 | * @example |
||
6674 | * |
||
6675 | * _.groupBy([4.2, 6.1, 6.4], function(n) { |
||
6676 | * return Math.floor(n); |
||
6677 | * }); |
||
6678 | * // => { '4': [4.2], '6': [6.1, 6.4] } |
||
6679 | * |
||
6680 | * _.groupBy([4.2, 6.1, 6.4], function(n) { |
||
6681 | * return this.floor(n); |
||
6682 | * }, Math); |
||
6683 | * // => { '4': [4.2], '6': [6.1, 6.4] } |
||
6684 | * |
||
6685 | * // using the `_.property` callback shorthand |
||
6686 | * _.groupBy(['one', 'two', 'three'], 'length'); |
||
6687 | * // => { '3': ['one', 'two'], '5': ['three'] } |
||
6688 | */ |
||
6689 | var groupBy = createAggregator(function(result, value, key) { |
||
6690 | if (hasOwnProperty.call(result, key)) { |
||
6691 | result[key].push(value); |
||
6692 | } else { |
||
6693 | result[key] = [value]; |
||
6694 | } |
||
6695 | }); |
||
6696 | |||
6697 | /** |
||
6698 | * Checks if `target` is in `collection` using |
||
6699 | * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) |
||
6700 | * for equality comparisons. If `fromIndex` is negative, it's used as the offset |
||
6701 | * from the end of `collection`. |
||
6702 | * |
||
6703 | * @static |
||
6704 | * @memberOf _ |
||
6705 | * @alias contains, include |
||
6706 | * @category Collection |
||
6707 | * @param {Array|Object|string} collection The collection to search. |
||
6708 | * @param {*} target The value to search for. |
||
6709 | * @param {number} [fromIndex=0] The index to search from. |
||
6710 | * @param- {Object} [guard] Enables use as a callback for functions like `_.reduce`. |
||
6711 | * @returns {boolean} Returns `true` if a matching element is found, else `false`. |
||
6712 | * @example |
||
6713 | * |
||
6714 | * _.includes([1, 2, 3], 1); |
||
6715 | * // => true |
||
6716 | * |
||
6717 | * _.includes([1, 2, 3], 1, 2); |
||
6718 | * // => false |
||
6719 | * |
||
6720 | * _.includes({ 'user': 'fred', 'age': 40 }, 'fred'); |
||
6721 | * // => true |
||
6722 | * |
||
6723 | * _.includes('pebbles', 'eb'); |
||
6724 | * // => true |
||
6725 | */ |
||
6726 | function includes(collection, target, fromIndex, guard) { |
||
6727 | var length = collection ? getLength(collection) : 0; |
||
6728 | if (!isLength(length)) { |
||
6729 | collection = values(collection); |
||
6730 | length = collection.length; |
||
6731 | } |
||
6732 | if (typeof fromIndex != 'number' || (guard && isIterateeCall(target, fromIndex, guard))) { |
||
6733 | fromIndex = 0; |
||
6734 | } else { |
||
6735 | fromIndex = fromIndex < 0 ? nativeMax(length + fromIndex, 0) : (fromIndex || 0); |
||
6736 | } |
||
6737 | return (typeof collection == 'string' || !isArray(collection) && isString(collection)) |
||
6738 | ? (fromIndex <= length && collection.indexOf(target, fromIndex) > -1) |
||
6739 | : (!!length && getIndexOf(collection, target, fromIndex) > -1); |
||
6740 | } |
||
6741 | |||
6742 | /** |
||
6743 | * Creates an object composed of keys generated from the results of running |
||
6744 | * each element of `collection` through `iteratee`. The corresponding value |
||
6745 | * of each key is the last element responsible for generating the key. The |
||
6746 | * iteratee function is bound to `thisArg` and invoked with three arguments: |
||
6747 | * (value, index|key, collection). |
||
6748 | * |
||
6749 | * If a property name is provided for `iteratee` the created `_.property` |
||
6750 | * style callback returns the property value of the given element. |
||
6751 | * |
||
6752 | * If a value is also provided for `thisArg` the created `_.matchesProperty` |
||
6753 | * style callback returns `true` for elements that have a matching property |
||
6754 | * value, else `false`. |
||
6755 | * |
||
6756 | * If an object is provided for `iteratee` the created `_.matches` style |
||
6757 | * callback returns `true` for elements that have the properties of the given |
||
6758 | * object, else `false`. |
||
6759 | * |
||
6760 | * @static |
||
6761 | * @memberOf _ |
||
6762 | * @category Collection |
||
6763 | * @param {Array|Object|string} collection The collection to iterate over. |
||
6764 | * @param {Function|Object|string} [iteratee=_.identity] The function invoked |
||
6765 | * per iteration. |
||
6766 | * @param {*} [thisArg] The `this` binding of `iteratee`. |
||
6767 | * @returns {Object} Returns the composed aggregate object. |
||
6768 | * @example |
||
6769 | * |
||
6770 | * var keyData = [ |
||
6771 | * { 'dir': 'left', 'code': 97 }, |
||
6772 | * { 'dir': 'right', 'code': 100 } |
||
6773 | * ]; |
||
6774 | * |
||
6775 | * _.indexBy(keyData, 'dir'); |
||
6776 | * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } } |
||
6777 | * |
||
6778 | * _.indexBy(keyData, function(object) { |
||
6779 | * return String.fromCharCode(object.code); |
||
6780 | * }); |
||
6781 | * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } } |
||
6782 | * |
||
6783 | * _.indexBy(keyData, function(object) { |
||
6784 | * return this.fromCharCode(object.code); |
||
6785 | * }, String); |
||
6786 | * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } } |
||
6787 | */ |
||
6788 | var indexBy = createAggregator(function(result, value, key) { |
||
6789 | result[key] = value; |
||
6790 | }); |
||
6791 | |||
6792 | /** |
||
6793 | * Invokes the method at `path` of each element in `collection`, returning |
||
6794 | * an array of the results of each invoked method. Any additional arguments |
||
6795 | * are provided to each invoked method. If `methodName` is a function it's |
||
6796 | * invoked for, and `this` bound to, each element in `collection`. |
||
6797 | * |
||
6798 | * @static |
||
6799 | * @memberOf _ |
||
6800 | * @category Collection |
||
6801 | * @param {Array|Object|string} collection The collection to iterate over. |
||
6802 | * @param {Array|Function|string} path The path of the method to invoke or |
||
6803 | * the function invoked per iteration. |
||
6804 | * @param {...*} [args] The arguments to invoke the method with. |
||
6805 | * @returns {Array} Returns the array of results. |
||
6806 | * @example |
||
6807 | * |
||
6808 | * _.invoke([[5, 1, 7], [3, 2, 1]], 'sort'); |
||
6809 | * // => [[1, 5, 7], [1, 2, 3]] |
||
6810 | * |
||
6811 | * _.invoke([123, 456], String.prototype.split, ''); |
||
6812 | * // => [['1', '2', '3'], ['4', '5', '6']] |
||
6813 | */ |
||
6814 | var invoke = restParam(function(collection, path, args) { |
||
6815 | var index = -1, |
||
6816 | isFunc = typeof path == 'function', |
||
6817 | isProp = isKey(path), |
||
6818 | result = isArrayLike(collection) ? Array(collection.length) : []; |
||
6819 | |||
6820 | baseEach(collection, function(value) { |
||
6821 | var func = isFunc ? path : ((isProp && value != null) ? value[path] : undefined); |
||
6822 | result[++index] = func ? func.apply(value, args) : invokePath(value, path, args); |
||
6823 | }); |
||
6824 | return result; |
||
6825 | }); |
||
6826 | |||
6827 | /** |
||
6828 | * Creates an array of values by running each element in `collection` through |
||
6829 | * `iteratee`. The `iteratee` is bound to `thisArg` and invoked with three |
||
6830 | * arguments: (value, index|key, collection). |
||
6831 | * |
||
6832 | * If a property name is provided for `iteratee` the created `_.property` |
||
6833 | * style callback returns the property value of the given element. |
||
6834 | * |
||
6835 | * If a value is also provided for `thisArg` the created `_.matchesProperty` |
||
6836 | * style callback returns `true` for elements that have a matching property |
||
6837 | * value, else `false`. |
||
6838 | * |
||
6839 | * If an object is provided for `iteratee` the created `_.matches` style |
||
6840 | * callback returns `true` for elements that have the properties of the given |
||
6841 | * object, else `false`. |
||
6842 | * |
||
6843 | * Many lodash methods are guarded to work as iteratees for methods like |
||
6844 | * `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`. |
||
6845 | * |
||
6846 | * The guarded methods are: |
||
6847 | * `ary`, `callback`, `chunk`, `clone`, `create`, `curry`, `curryRight`, |
||
6848 | * `drop`, `dropRight`, `every`, `fill`, `flatten`, `invert`, `max`, `min`, |
||
6849 | * `parseInt`, `slice`, `sortBy`, `take`, `takeRight`, `template`, `trim`, |
||
6850 | * `trimLeft`, `trimRight`, `trunc`, `random`, `range`, `sample`, `some`, |
||
6851 | * `sum`, `uniq`, and `words` |
||
6852 | * |
||
6853 | * @static |
||
6854 | * @memberOf _ |
||
6855 | * @alias collect |
||
6856 | * @category Collection |
||
6857 | * @param {Array|Object|string} collection The collection to iterate over. |
||
6858 | * @param {Function|Object|string} [iteratee=_.identity] The function invoked |
||
6859 | * per iteration. |
||
6860 | * @param {*} [thisArg] The `this` binding of `iteratee`. |
||
6861 | * @returns {Array} Returns the new mapped array. |
||
6862 | * @example |
||
6863 | * |
||
6864 | * function timesThree(n) { |
||
6865 | * return n * 3; |
||
6866 | * } |
||
6867 | * |
||
6868 | * _.map([1, 2], timesThree); |
||
6869 | * // => [3, 6] |
||
6870 | * |
||
6871 | * _.map({ 'a': 1, 'b': 2 }, timesThree); |
||
6872 | * // => [3, 6] (iteration order is not guaranteed) |
||
6873 | * |
||
6874 | * var users = [ |
||
6875 | * { 'user': 'barney' }, |
||
6876 | * { 'user': 'fred' } |
||
6877 | * ]; |
||
6878 | * |
||
6879 | * // using the `_.property` callback shorthand |
||
6880 | * _.map(users, 'user'); |
||
6881 | * // => ['barney', 'fred'] |
||
6882 | */ |
||
6883 | function map(collection, iteratee, thisArg) { |
||
6884 | var func = isArray(collection) ? arrayMap : baseMap; |
||
6885 | iteratee = getCallback(iteratee, thisArg, 3); |
||
6886 | return func(collection, iteratee); |
||
6887 | } |
||
6888 | |||
6889 | /** |
||
6890 | * Creates an array of elements split into two groups, the first of which |
||
6891 | * contains elements `predicate` returns truthy for, while the second of which |
||
6892 | * contains elements `predicate` returns falsey for. The predicate is bound |
||
6893 | * to `thisArg` and invoked with three arguments: (value, index|key, collection). |
||
6894 | * |
||
6895 | * If a property name is provided for `predicate` the created `_.property` |
||
6896 | * style callback returns the property value of the given element. |
||
6897 | * |
||
6898 | * If a value is also provided for `thisArg` the created `_.matchesProperty` |
||
6899 | * style callback returns `true` for elements that have a matching property |
||
6900 | * value, else `false`. |
||
6901 | * |
||
6902 | * If an object is provided for `predicate` the created `_.matches` style |
||
6903 | * callback returns `true` for elements that have the properties of the given |
||
6904 | * object, else `false`. |
||
6905 | * |
||
6906 | * @static |
||
6907 | * @memberOf _ |
||
6908 | * @category Collection |
||
6909 | * @param {Array|Object|string} collection The collection to iterate over. |
||
6910 | * @param {Function|Object|string} [predicate=_.identity] The function invoked |
||
6911 | * per iteration. |
||
6912 | * @param {*} [thisArg] The `this` binding of `predicate`. |
||
6913 | * @returns {Array} Returns the array of grouped elements. |
||
6914 | * @example |
||
6915 | * |
||
6916 | * _.partition([1, 2, 3], function(n) { |
||
6917 | * return n % 2; |
||
6918 | * }); |
||
6919 | * // => [[1, 3], [2]] |
||
6920 | * |
||
6921 | * _.partition([1.2, 2.3, 3.4], function(n) { |
||
6922 | * return this.floor(n) % 2; |
||
6923 | * }, Math); |
||
6924 | * // => [[1.2, 3.4], [2.3]] |
||
6925 | * |
||
6926 | * var users = [ |
||
6927 | * { 'user': 'barney', 'age': 36, 'active': false }, |
||
6928 | * { 'user': 'fred', 'age': 40, 'active': true }, |
||
6929 | * { 'user': 'pebbles', 'age': 1, 'active': false } |
||
6930 | * ]; |
||
6931 | * |
||
6932 | * var mapper = function(array) { |
||
6933 | * return _.pluck(array, 'user'); |
||
6934 | * }; |
||
6935 | * |
||
6936 | * // using the `_.matches` callback shorthand |
||
6937 | * _.map(_.partition(users, { 'age': 1, 'active': false }), mapper); |
||
6938 | * // => [['pebbles'], ['barney', 'fred']] |
||
6939 | * |
||
6940 | * // using the `_.matchesProperty` callback shorthand |
||
6941 | * _.map(_.partition(users, 'active', false), mapper); |
||
6942 | * // => [['barney', 'pebbles'], ['fred']] |
||
6943 | * |
||
6944 | * // using the `_.property` callback shorthand |
||
6945 | * _.map(_.partition(users, 'active'), mapper); |
||
6946 | * // => [['fred'], ['barney', 'pebbles']] |
||
6947 | */ |
||
6948 | var partition = createAggregator(function(result, value, key) { |
||
6949 | result[key ? 0 : 1].push(value); |
||
6950 | }, function() { return [[], []]; }); |
||
6951 | |||
6952 | /** |
||
6953 | * Gets the property value of `path` from all elements in `collection`. |
||
6954 | * |
||
6955 | * @static |
||
6956 | * @memberOf _ |
||
6957 | * @category Collection |
||
6958 | * @param {Array|Object|string} collection The collection to iterate over. |
||
6959 | * @param {Array|string} path The path of the property to pluck. |
||
6960 | * @returns {Array} Returns the property values. |
||
6961 | * @example |
||
6962 | * |
||
6963 | * var users = [ |
||
6964 | * { 'user': 'barney', 'age': 36 }, |
||
6965 | * { 'user': 'fred', 'age': 40 } |
||
6966 | * ]; |
||
6967 | * |
||
6968 | * _.pluck(users, 'user'); |
||
6969 | * // => ['barney', 'fred'] |
||
6970 | * |
||
6971 | * var userIndex = _.indexBy(users, 'user'); |
||
6972 | * _.pluck(userIndex, 'age'); |
||
6973 | * // => [36, 40] (iteration order is not guaranteed) |
||
6974 | */ |
||
6975 | function pluck(collection, path) { |
||
6976 | return map(collection, property(path)); |
||
6977 | } |
||
6978 | |||
6979 | /** |
||
6980 | * Reduces `collection` to a value which is the accumulated result of running |
||
6981 | * each element in `collection` through `iteratee`, where each successive |
||
6982 | * invocation is supplied the return value of the previous. If `accumulator` |
||
6983 | * is not provided the first element of `collection` is used as the initial |
||
6984 | * value. The `iteratee` is bound to `thisArg` and invoked with four arguments: |
||
6985 | * (accumulator, value, index|key, collection). |
||
6986 | * |
||
6987 | * Many lodash methods are guarded to work as iteratees for methods like |
||
6988 | * `_.reduce`, `_.reduceRight`, and `_.transform`. |
||
6989 | * |
||
6990 | * The guarded methods are: |
||
6991 | * `assign`, `defaults`, `defaultsDeep`, `includes`, `merge`, `sortByAll`, |
||
6992 | * and `sortByOrder` |
||
6993 | * |
||
6994 | * @static |
||
6995 | * @memberOf _ |
||
6996 | * @alias foldl, inject |
||
6997 | * @category Collection |
||
6998 | * @param {Array|Object|string} collection The collection to iterate over. |
||
6999 | * @param {Function} [iteratee=_.identity] The function invoked per iteration. |
||
7000 | * @param {*} [accumulator] The initial value. |
||
7001 | * @param {*} [thisArg] The `this` binding of `iteratee`. |
||
7002 | * @returns {*} Returns the accumulated value. |
||
7003 | * @example |
||
7004 | * |
||
7005 | * _.reduce([1, 2], function(total, n) { |
||
7006 | * return total + n; |
||
7007 | * }); |
||
7008 | * // => 3 |
||
7009 | * |
||
7010 | * _.reduce({ 'a': 1, 'b': 2 }, function(result, n, key) { |
||
7011 | * result[key] = n * 3; |
||
7012 | * return result; |
||
7013 | * }, {}); |
||
7014 | * // => { 'a': 3, 'b': 6 } (iteration order is not guaranteed) |
||
7015 | */ |
||
7016 | var reduce = createReduce(arrayReduce, baseEach); |
||
7017 | |||
7018 | /** |
||
7019 | * This method is like `_.reduce` except that it iterates over elements of |
||
7020 | * `collection` from right to left. |
||
7021 | * |
||
7022 | * @static |
||
7023 | * @memberOf _ |
||
7024 | * @alias foldr |
||
7025 | * @category Collection |
||
7026 | * @param {Array|Object|string} collection The collection to iterate over. |
||
7027 | * @param {Function} [iteratee=_.identity] The function invoked per iteration. |
||
7028 | * @param {*} [accumulator] The initial value. |
||
7029 | * @param {*} [thisArg] The `this` binding of `iteratee`. |
||
7030 | * @returns {*} Returns the accumulated value. |
||
7031 | * @example |
||
7032 | * |
||
7033 | * var array = [[0, 1], [2, 3], [4, 5]]; |
||
7034 | * |
||
7035 | * _.reduceRight(array, function(flattened, other) { |
||
7036 | * return flattened.concat(other); |
||
7037 | * }, []); |
||
7038 | * // => [4, 5, 2, 3, 0, 1] |
||
7039 | */ |
||
7040 | var reduceRight = createReduce(arrayReduceRight, baseEachRight); |
||
7041 | |||
7042 | /** |
||
7043 | * The opposite of `_.filter`; this method returns the elements of `collection` |
||
7044 | * that `predicate` does **not** return truthy for. |
||
7045 | * |
||
7046 | * @static |
||
7047 | * @memberOf _ |
||
7048 | * @category Collection |
||
7049 | * @param {Array|Object|string} collection The collection to iterate over. |
||
7050 | * @param {Function|Object|string} [predicate=_.identity] The function invoked |
||
7051 | * per iteration. |
||
7052 | * @param {*} [thisArg] The `this` binding of `predicate`. |
||
7053 | * @returns {Array} Returns the new filtered array. |
||
7054 | * @example |
||
7055 | * |
||
7056 | * _.reject([1, 2, 3, 4], function(n) { |
||
7057 | * return n % 2 == 0; |
||
7058 | * }); |
||
7059 | * // => [1, 3] |
||
7060 | * |
||
7061 | * var users = [ |
||
7062 | * { 'user': 'barney', 'age': 36, 'active': false }, |
||
7063 | * { 'user': 'fred', 'age': 40, 'active': true } |
||
7064 | * ]; |
||
7065 | * |
||
7066 | * // using the `_.matches` callback shorthand |
||
7067 | * _.pluck(_.reject(users, { 'age': 40, 'active': true }), 'user'); |
||
7068 | * // => ['barney'] |
||
7069 | * |
||
7070 | * // using the `_.matchesProperty` callback shorthand |
||
7071 | * _.pluck(_.reject(users, 'active', false), 'user'); |
||
7072 | * // => ['fred'] |
||
7073 | * |
||
7074 | * // using the `_.property` callback shorthand |
||
7075 | * _.pluck(_.reject(users, 'active'), 'user'); |
||
7076 | * // => ['barney'] |
||
7077 | */ |
||
7078 | function reject(collection, predicate, thisArg) { |
||
7079 | var func = isArray(collection) ? arrayFilter : baseFilter; |
||
7080 | predicate = getCallback(predicate, thisArg, 3); |
||
7081 | return func(collection, function(value, index, collection) { |
||
7082 | return !predicate(value, index, collection); |
||
7083 | }); |
||
7084 | } |
||
7085 | |||
7086 | /** |
||
7087 | * Gets a random element or `n` random elements from a collection. |
||
7088 | * |
||
7089 | * @static |
||
7090 | * @memberOf _ |
||
7091 | * @category Collection |
||
7092 | * @param {Array|Object|string} collection The collection to sample. |
||
7093 | * @param {number} [n] The number of elements to sample. |
||
7094 | * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. |
||
7095 | * @returns {*} Returns the random sample(s). |
||
7096 | * @example |
||
7097 | * |
||
7098 | * _.sample([1, 2, 3, 4]); |
||
7099 | * // => 2 |
||
7100 | * |
||
7101 | * _.sample([1, 2, 3, 4], 2); |
||
7102 | * // => [3, 1] |
||
7103 | */ |
||
7104 | function sample(collection, n, guard) { |
||
7105 | if (guard ? isIterateeCall(collection, n, guard) : n == null) { |
||
7106 | collection = toIterable(collection); |
||
7107 | var length = collection.length; |
||
7108 | return length > 0 ? collection[baseRandom(0, length - 1)] : undefined; |
||
7109 | } |
||
7110 | var index = -1, |
||
7111 | result = toArray(collection), |
||
7112 | length = result.length, |
||
7113 | lastIndex = length - 1; |
||
7114 | |||
7115 | n = nativeMin(n < 0 ? 0 : (+n || 0), length); |
||
7116 | while (++index < n) { |
||
7117 | var rand = baseRandom(index, lastIndex), |
||
7118 | value = result[rand]; |
||
7119 | |||
7120 | result[rand] = result[index]; |
||
7121 | result[index] = value; |
||
7122 | } |
||
7123 | result.length = n; |
||
7124 | return result; |
||
7125 | } |
||
7126 | |||
7127 | /** |
||
7128 | * Creates an array of shuffled values, using a version of the |
||
7129 | * [Fisher-Yates shuffle](https://en.wikipedia.org/wiki/Fisher-Yates_shuffle). |
||
7130 | * |
||
7131 | * @static |
||
7132 | * @memberOf _ |
||
7133 | * @category Collection |
||
7134 | * @param {Array|Object|string} collection The collection to shuffle. |
||
7135 | * @returns {Array} Returns the new shuffled array. |
||
7136 | * @example |
||
7137 | * |
||
7138 | * _.shuffle([1, 2, 3, 4]); |
||
7139 | * // => [4, 1, 3, 2] |
||
7140 | */ |
||
7141 | function shuffle(collection) { |
||
7142 | return sample(collection, POSITIVE_INFINITY); |
||
7143 | } |
||
7144 | |||
7145 | /** |
||
7146 | * Gets the size of `collection` by returning its length for array-like |
||
7147 | * values or the number of own enumerable properties for objects. |
||
7148 | * |
||
7149 | * @static |
||
7150 | * @memberOf _ |
||
7151 | * @category Collection |
||
7152 | * @param {Array|Object|string} collection The collection to inspect. |
||
7153 | * @returns {number} Returns the size of `collection`. |
||
7154 | * @example |
||
7155 | * |
||
7156 | * _.size([1, 2, 3]); |
||
7157 | * // => 3 |
||
7158 | * |
||
7159 | * _.size({ 'a': 1, 'b': 2 }); |
||
7160 | * // => 2 |
||
7161 | * |
||
7162 | * _.size('pebbles'); |
||
7163 | * // => 7 |
||
7164 | */ |
||
7165 | function size(collection) { |
||
7166 | var length = collection ? getLength(collection) : 0; |
||
7167 | return isLength(length) ? length : keys(collection).length; |
||
7168 | } |
||
7169 | |||
7170 | /** |
||
7171 | * Checks if `predicate` returns truthy for **any** element of `collection`. |
||
7172 | * The function returns as soon as it finds a passing value and does not iterate |
||
7173 | * over the entire collection. The predicate is bound to `thisArg` and invoked |
||
7174 | * with three arguments: (value, index|key, collection). |
||
7175 | * |
||
7176 | * If a property name is provided for `predicate` the created `_.property` |
||
7177 | * style callback returns the property value of the given element. |
||
7178 | * |
||
7179 | * If a value is also provided for `thisArg` the created `_.matchesProperty` |
||
7180 | * style callback returns `true` for elements that have a matching property |
||
7181 | * value, else `false`. |
||
7182 | * |
||
7183 | * If an object is provided for `predicate` the created `_.matches` style |
||
7184 | * callback returns `true` for elements that have the properties of the given |
||
7185 | * object, else `false`. |
||
7186 | * |
||
7187 | * @static |
||
7188 | * @memberOf _ |
||
7189 | * @alias any |
||
7190 | * @category Collection |
||
7191 | * @param {Array|Object|string} collection The collection to iterate over. |
||
7192 | * @param {Function|Object|string} [predicate=_.identity] The function invoked |
||
7193 | * per iteration. |
||
7194 | * @param {*} [thisArg] The `this` binding of `predicate`. |
||
7195 | * @returns {boolean} Returns `true` if any element passes the predicate check, |
||
7196 | * else `false`. |
||
7197 | * @example |
||
7198 | * |
||
7199 | * _.some([null, 0, 'yes', false], Boolean); |
||
7200 | * // => true |
||
7201 | * |
||
7202 | * var users = [ |
||
7203 | * { 'user': 'barney', 'active': true }, |
||
7204 | * { 'user': 'fred', 'active': false } |
||
7205 | * ]; |
||
7206 | * |
||
7207 | * // using the `_.matches` callback shorthand |
||
7208 | * _.some(users, { 'user': 'barney', 'active': false }); |
||
7209 | * // => false |
||
7210 | * |
||
7211 | * // using the `_.matchesProperty` callback shorthand |
||
7212 | * _.some(users, 'active', false); |
||
7213 | * // => true |
||
7214 | * |
||
7215 | * // using the `_.property` callback shorthand |
||
7216 | * _.some(users, 'active'); |
||
7217 | * // => true |
||
7218 | */ |
||
7219 | function some(collection, predicate, thisArg) { |
||
7220 | var func = isArray(collection) ? arraySome : baseSome; |
||
7221 | if (thisArg && isIterateeCall(collection, predicate, thisArg)) { |
||
7222 | predicate = undefined; |
||
7223 | } |
||
7224 | if (typeof predicate != 'function' || thisArg !== undefined) { |
||
7225 | predicate = getCallback(predicate, thisArg, 3); |
||
7226 | } |
||
7227 | return func(collection, predicate); |
||
7228 | } |
||
7229 | |||
7230 | /** |
||
7231 | * Creates an array of elements, sorted in ascending order by the results of |
||
7232 | * running each element in a collection through `iteratee`. This method performs |
||
7233 | * a stable sort, that is, it preserves the original sort order of equal elements. |
||
7234 | * The `iteratee` is bound to `thisArg` and invoked with three arguments: |
||
7235 | * (value, index|key, collection). |
||
7236 | * |
||
7237 | * If a property name is provided for `iteratee` the created `_.property` |
||
7238 | * style callback returns the property value of the given element. |
||
7239 | * |
||
7240 | * If a value is also provided for `thisArg` the created `_.matchesProperty` |
||
7241 | * style callback returns `true` for elements that have a matching property |
||
7242 | * value, else `false`. |
||
7243 | * |
||
7244 | * If an object is provided for `iteratee` the created `_.matches` style |
||
7245 | * callback returns `true` for elements that have the properties of the given |
||
7246 | * object, else `false`. |
||
7247 | * |
||
7248 | * @static |
||
7249 | * @memberOf _ |
||
7250 | * @category Collection |
||
7251 | * @param {Array|Object|string} collection The collection to iterate over. |
||
7252 | * @param {Function|Object|string} [iteratee=_.identity] The function invoked |
||
7253 | * per iteration. |
||
7254 | * @param {*} [thisArg] The `this` binding of `iteratee`. |
||
7255 | * @returns {Array} Returns the new sorted array. |
||
7256 | * @example |
||
7257 | * |
||
7258 | * _.sortBy([1, 2, 3], function(n) { |
||
7259 | * return Math.sin(n); |
||
7260 | * }); |
||
7261 | * // => [3, 1, 2] |
||
7262 | * |
||
7263 | * _.sortBy([1, 2, 3], function(n) { |
||
7264 | * return this.sin(n); |
||
7265 | * }, Math); |
||
7266 | * // => [3, 1, 2] |
||
7267 | * |
||
7268 | * var users = [ |
||
7269 | * { 'user': 'fred' }, |
||
7270 | * { 'user': 'pebbles' }, |
||
7271 | * { 'user': 'barney' } |
||
7272 | * ]; |
||
7273 | * |
||
7274 | * // using the `_.property` callback shorthand |
||
7275 | * _.pluck(_.sortBy(users, 'user'), 'user'); |
||
7276 | * // => ['barney', 'fred', 'pebbles'] |
||
7277 | */ |
||
7278 | function sortBy(collection, iteratee, thisArg) { |
||
7279 | if (collection == null) { |
||
7280 | return []; |
||
7281 | } |
||
7282 | if (thisArg && isIterateeCall(collection, iteratee, thisArg)) { |
||
7283 | iteratee = undefined; |
||
7284 | } |
||
7285 | var index = -1; |
||
7286 | iteratee = getCallback(iteratee, thisArg, 3); |
||
7287 | |||
7288 | var result = baseMap(collection, function(value, key, collection) { |
||
7289 | return { 'criteria': iteratee(value, key, collection), 'index': ++index, 'value': value }; |
||
7290 | }); |
||
7291 | return baseSortBy(result, compareAscending); |
||
7292 | } |
||
7293 | |||
7294 | /** |
||
7295 | * This method is like `_.sortBy` except that it can sort by multiple iteratees |
||
7296 | * or property names. |
||
7297 | * |
||
7298 | * If a property name is provided for an iteratee the created `_.property` |
||
7299 | * style callback returns the property value of the given element. |
||
7300 | * |
||
7301 | * If an object is provided for an iteratee the created `_.matches` style |
||
7302 | * callback returns `true` for elements that have the properties of the given |
||
7303 | * object, else `false`. |
||
7304 | * |
||
7305 | * @static |
||
7306 | * @memberOf _ |
||
7307 | * @category Collection |
||
7308 | * @param {Array|Object|string} collection The collection to iterate over. |
||
7309 | * @param {...(Function|Function[]|Object|Object[]|string|string[])} iteratees |
||
7310 | * The iteratees to sort by, specified as individual values or arrays of values. |
||
7311 | * @returns {Array} Returns the new sorted array. |
||
7312 | * @example |
||
7313 | * |
||
7314 | * var users = [ |
||
7315 | * { 'user': 'fred', 'age': 48 }, |
||
7316 | * { 'user': 'barney', 'age': 36 }, |
||
7317 | * { 'user': 'fred', 'age': 42 }, |
||
7318 | * { 'user': 'barney', 'age': 34 } |
||
7319 | * ]; |
||
7320 | * |
||
7321 | * _.map(_.sortByAll(users, ['user', 'age']), _.values); |
||
7322 | * // => [['barney', 34], ['barney', 36], ['fred', 42], ['fred', 48]] |
||
7323 | * |
||
7324 | * _.map(_.sortByAll(users, 'user', function(chr) { |
||
7325 | * return Math.floor(chr.age / 10); |
||
7326 | * }), _.values); |
||
7327 | * // => [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 42]] |
||
7328 | */ |
||
7329 | var sortByAll = restParam(function(collection, iteratees) { |
||
7330 | if (collection == null) { |
||
7331 | return []; |
||
7332 | } |
||
7333 | var guard = iteratees[2]; |
||
7334 | if (guard && isIterateeCall(iteratees[0], iteratees[1], guard)) { |
||
7335 | iteratees.length = 1; |
||
7336 | } |
||
7337 | return baseSortByOrder(collection, baseFlatten(iteratees), []); |
||
7338 | }); |
||
7339 | |||
7340 | /** |
||
7341 | * This method is like `_.sortByAll` except that it allows specifying the |
||
7342 | * sort orders of the iteratees to sort by. If `orders` is unspecified, all |
||
7343 | * values are sorted in ascending order. Otherwise, a value is sorted in |
||
7344 | * ascending order if its corresponding order is "asc", and descending if "desc". |
||
7345 | * |
||
7346 | * If a property name is provided for an iteratee the created `_.property` |
||
7347 | * style callback returns the property value of the given element. |
||
7348 | * |
||
7349 | * If an object is provided for an iteratee the created `_.matches` style |
||
7350 | * callback returns `true` for elements that have the properties of the given |
||
7351 | * object, else `false`. |
||
7352 | * |
||
7353 | * @static |
||
7354 | * @memberOf _ |
||
7355 | * @category Collection |
||
7356 | * @param {Array|Object|string} collection The collection to iterate over. |
||
7357 | * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by. |
||
7358 | * @param {boolean[]} [orders] The sort orders of `iteratees`. |
||
7359 | * @param- {Object} [guard] Enables use as a callback for functions like `_.reduce`. |
||
7360 | * @returns {Array} Returns the new sorted array. |
||
7361 | * @example |
||
7362 | * |
||
7363 | * var users = [ |
||
7364 | * { 'user': 'fred', 'age': 48 }, |
||
7365 | * { 'user': 'barney', 'age': 34 }, |
||
7366 | * { 'user': 'fred', 'age': 42 }, |
||
7367 | * { 'user': 'barney', 'age': 36 } |
||
7368 | * ]; |
||
7369 | * |
||
7370 | * // sort by `user` in ascending order and by `age` in descending order |
||
7371 | * _.map(_.sortByOrder(users, ['user', 'age'], ['asc', 'desc']), _.values); |
||
7372 | * // => [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 42]] |
||
7373 | */ |
||
7374 | function sortByOrder(collection, iteratees, orders, guard) { |
||
7375 | if (collection == null) { |
||
7376 | return []; |
||
7377 | } |
||
7378 | if (guard && isIterateeCall(iteratees, orders, guard)) { |
||
7379 | orders = undefined; |
||
7380 | } |
||
7381 | if (!isArray(iteratees)) { |
||
7382 | iteratees = iteratees == null ? [] : [iteratees]; |
||
7383 | } |
||
7384 | if (!isArray(orders)) { |
||
7385 | orders = orders == null ? [] : [orders]; |
||
7386 | } |
||
7387 | return baseSortByOrder(collection, iteratees, orders); |
||
7388 | } |
||
7389 | |||
7390 | /** |
||
7391 | * Performs a deep comparison between each element in `collection` and the |
||
7392 | * source object, returning an array of all elements that have equivalent |
||
7393 | * property values. |
||
7394 | * |
||
7395 | * **Note:** This method supports comparing arrays, booleans, `Date` objects, |
||
7396 | * numbers, `Object` objects, regexes, and strings. Objects are compared by |
||
7397 | * their own, not inherited, enumerable properties. For comparing a single |
||
7398 | * own or inherited property value see `_.matchesProperty`. |
||
7399 | * |
||
7400 | * @static |
||
7401 | * @memberOf _ |
||
7402 | * @category Collection |
||
7403 | * @param {Array|Object|string} collection The collection to search. |
||
7404 | * @param {Object} source The object of property values to match. |
||
7405 | * @returns {Array} Returns the new filtered array. |
||
7406 | * @example |
||
7407 | * |
||
7408 | * var users = [ |
||
7409 | * { 'user': 'barney', 'age': 36, 'active': false, 'pets': ['hoppy'] }, |
||
7410 | * { 'user': 'fred', 'age': 40, 'active': true, 'pets': ['baby puss', 'dino'] } |
||
7411 | * ]; |
||
7412 | * |
||
7413 | * _.pluck(_.where(users, { 'age': 36, 'active': false }), 'user'); |
||
7414 | * // => ['barney'] |
||
7415 | * |
||
7416 | * _.pluck(_.where(users, { 'pets': ['dino'] }), 'user'); |
||
7417 | * // => ['fred'] |
||
7418 | */ |
||
7419 | function where(collection, source) { |
||
7420 | return filter(collection, baseMatches(source)); |
||
7421 | } |
||
7422 | |||
7423 | /*------------------------------------------------------------------------*/ |
||
7424 | |||
7425 | /** |
||
7426 | * Gets the number of milliseconds that have elapsed since the Unix epoch |
||
7427 | * (1 January 1970 00:00:00 UTC). |
||
7428 | * |
||
7429 | * @static |
||
7430 | * @memberOf _ |
||
7431 | * @category Date |
||
7432 | * @example |
||
7433 | * |
||
7434 | * _.defer(function(stamp) { |
||
7435 | * console.log(_.now() - stamp); |
||
7436 | * }, _.now()); |
||
7437 | * // => logs the number of milliseconds it took for the deferred function to be invoked |
||
7438 | */ |
||
7439 | var now = nativeNow || function() { |
||
7440 | return new Date().getTime(); |
||
7441 | }; |
||
7442 | |||
7443 | /*------------------------------------------------------------------------*/ |
||
7444 | |||
7445 | /** |
||
7446 | * The opposite of `_.before`; this method creates a function that invokes |
||
7447 | * `func` once it's called `n` or more times. |
||
7448 | * |
||
7449 | * @static |
||
7450 | * @memberOf _ |
||
7451 | * @category Function |
||
7452 | * @param {number} n The number of calls before `func` is invoked. |
||
7453 | * @param {Function} func The function to restrict. |
||
7454 | * @returns {Function} Returns the new restricted function. |
||
7455 | * @example |
||
7456 | * |
||
7457 | * var saves = ['profile', 'settings']; |
||
7458 | * |
||
7459 | * var done = _.after(saves.length, function() { |
||
7460 | * console.log('done saving!'); |
||
7461 | * }); |
||
7462 | * |
||
7463 | * _.forEach(saves, function(type) { |
||
7464 | * asyncSave({ 'type': type, 'complete': done }); |
||
7465 | * }); |
||
7466 | * // => logs 'done saving!' after the two async saves have completed |
||
7467 | */ |
||
7468 | function after(n, func) { |
||
7469 | if (typeof func != 'function') { |
||
7470 | if (typeof n == 'function') { |
||
7471 | var temp = n; |
||
7472 | n = func; |
||
7473 | func = temp; |
||
7474 | } else { |
||
7475 | throw new TypeError(FUNC_ERROR_TEXT); |
||
7476 | } |
||
7477 | } |
||
7478 | n = nativeIsFinite(n = +n) ? n : 0; |
||
7479 | return function() { |
||
7480 | if (--n < 1) { |
||
7481 | return func.apply(this, arguments); |
||
7482 | } |
||
7483 | }; |
||
7484 | } |
||
7485 | |||
7486 | /** |
||
7487 | * Creates a function that accepts up to `n` arguments ignoring any |
||
7488 | * additional arguments. |
||
7489 | * |
||
7490 | * @static |
||
7491 | * @memberOf _ |
||
7492 | * @category Function |
||
7493 | * @param {Function} func The function to cap arguments for. |
||
7494 | * @param {number} [n=func.length] The arity cap. |
||
7495 | * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. |
||
7496 | * @returns {Function} Returns the new function. |
||
7497 | * @example |
||
7498 | * |
||
7499 | * _.map(['6', '8', '10'], _.ary(parseInt, 1)); |
||
7500 | * // => [6, 8, 10] |
||
7501 | */ |
||
7502 | function ary(func, n, guard) { |
||
7503 | if (guard && isIterateeCall(func, n, guard)) { |
||
7504 | n = undefined; |
||
7505 | } |
||
7506 | n = (func && n == null) ? func.length : nativeMax(+n || 0, 0); |
||
7507 | return createWrapper(func, ARY_FLAG, undefined, undefined, undefined, undefined, n); |
||
7508 | } |
||
7509 | |||
7510 | /** |
||
7511 | * Creates a function that invokes `func`, with the `this` binding and arguments |
||
7512 | * of the created function, while it's called less than `n` times. Subsequent |
||
7513 | * calls to the created function return the result of the last `func` invocation. |
||
7514 | * |
||
7515 | * @static |
||
7516 | * @memberOf _ |
||
7517 | * @category Function |
||
7518 | * @param {number} n The number of calls at which `func` is no longer invoked. |
||
7519 | * @param {Function} func The function to restrict. |
||
7520 | * @returns {Function} Returns the new restricted function. |
||
7521 | * @example |
||
7522 | * |
||
7523 | * jQuery('#add').on('click', _.before(5, addContactToList)); |
||
7524 | * // => allows adding up to 4 contacts to the list |
||
7525 | */ |
||
7526 | function before(n, func) { |
||
7527 | var result; |
||
7528 | if (typeof func != 'function') { |
||
7529 | if (typeof n == 'function') { |
||
7530 | var temp = n; |
||
7531 | n = func; |
||
7532 | func = temp; |
||
7533 | } else { |
||
7534 | throw new TypeError(FUNC_ERROR_TEXT); |
||
7535 | } |
||
7536 | } |
||
7537 | return function() { |
||
7538 | if (--n > 0) { |
||
7539 | result = func.apply(this, arguments); |
||
7540 | } |
||
7541 | if (n <= 1) { |
||
7542 | func = undefined; |
||
7543 | } |
||
7544 | return result; |
||
7545 | }; |
||
7546 | } |
||
7547 | |||
7548 | /** |
||
7549 | * Creates a function that invokes `func` with the `this` binding of `thisArg` |
||
7550 | * and prepends any additional `_.bind` arguments to those provided to the |
||
7551 | * bound function. |
||
7552 | * |
||
7553 | * The `_.bind.placeholder` value, which defaults to `_` in monolithic builds, |
||
7554 | * may be used as a placeholder for partially applied arguments. |
||
7555 | * |
||
7556 | * **Note:** Unlike native `Function#bind` this method does not set the "length" |
||
7557 | * property of bound functions. |
||
7558 | * |
||
7559 | * @static |
||
7560 | * @memberOf _ |
||
7561 | * @category Function |
||
7562 | * @param {Function} func The function to bind. |
||
7563 | * @param {*} thisArg The `this` binding of `func`. |
||
7564 | * @param {...*} [partials] The arguments to be partially applied. |
||
7565 | * @returns {Function} Returns the new bound function. |
||
7566 | * @example |
||
7567 | * |
||
7568 | * var greet = function(greeting, punctuation) { |
||
7569 | * return greeting + ' ' + this.user + punctuation; |
||
7570 | * }; |
||
7571 | * |
||
7572 | * var object = { 'user': 'fred' }; |
||
7573 | * |
||
7574 | * var bound = _.bind(greet, object, 'hi'); |
||
7575 | * bound('!'); |
||
7576 | * // => 'hi fred!' |
||
7577 | * |
||
7578 | * // using placeholders |
||
7579 | * var bound = _.bind(greet, object, _, '!'); |
||
7580 | * bound('hi'); |
||
7581 | * // => 'hi fred!' |
||
7582 | */ |
||
7583 | var bind = restParam(function(func, thisArg, partials) { |
||
7584 | var bitmask = BIND_FLAG; |
||
7585 | if (partials.length) { |
||
7586 | var holders = replaceHolders(partials, bind.placeholder); |
||
7587 | bitmask |= PARTIAL_FLAG; |
||
7588 | } |
||
7589 | return createWrapper(func, bitmask, thisArg, partials, holders); |
||
7590 | }); |
||
7591 | |||
7592 | /** |
||
7593 | * Binds methods of an object to the object itself, overwriting the existing |
||
7594 | * method. Method names may be specified as individual arguments or as arrays |
||
7595 | * of method names. If no method names are provided all enumerable function |
||
7596 | * properties, own and inherited, of `object` are bound. |
||
7597 | * |
||
7598 | * **Note:** This method does not set the "length" property of bound functions. |
||
7599 | * |
||
7600 | * @static |
||
7601 | * @memberOf _ |
||
7602 | * @category Function |
||
7603 | * @param {Object} object The object to bind and assign the bound methods to. |
||
7604 | * @param {...(string|string[])} [methodNames] The object method names to bind, |
||
7605 | * specified as individual method names or arrays of method names. |
||
7606 | * @returns {Object} Returns `object`. |
||
7607 | * @example |
||
7608 | * |
||
7609 | * var view = { |
||
7610 | * 'label': 'docs', |
||
7611 | * 'onClick': function() { |
||
7612 | * console.log('clicked ' + this.label); |
||
7613 | * } |
||
7614 | * }; |
||
7615 | * |
||
7616 | * _.bindAll(view); |
||
7617 | * jQuery('#docs').on('click', view.onClick); |
||
7618 | * // => logs 'clicked docs' when the element is clicked |
||
7619 | */ |
||
7620 | var bindAll = restParam(function(object, methodNames) { |
||
7621 | methodNames = methodNames.length ? baseFlatten(methodNames) : functions(object); |
||
7622 | |||
7623 | var index = -1, |
||
7624 | length = methodNames.length; |
||
7625 | |||
7626 | while (++index < length) { |
||
7627 | var key = methodNames[index]; |
||
7628 | object[key] = createWrapper(object[key], BIND_FLAG, object); |
||
7629 | } |
||
7630 | return object; |
||
7631 | }); |
||
7632 | |||
7633 | /** |
||
7634 | * Creates a function that invokes the method at `object[key]` and prepends |
||
7635 | * any additional `_.bindKey` arguments to those provided to the bound function. |
||
7636 | * |
||
7637 | * This method differs from `_.bind` by allowing bound functions to reference |
||
7638 | * methods that may be redefined or don't yet exist. |
||
7639 | * See [Peter Michaux's article](http://peter.michaux.ca/articles/lazy-function-definition-pattern) |
||
7640 | * for more details. |
||
7641 | * |
||
7642 | * The `_.bindKey.placeholder` value, which defaults to `_` in monolithic |
||
7643 | * builds, may be used as a placeholder for partially applied arguments. |
||
7644 | * |
||
7645 | * @static |
||
7646 | * @memberOf _ |
||
7647 | * @category Function |
||
7648 | * @param {Object} object The object the method belongs to. |
||
7649 | * @param {string} key The key of the method. |
||
7650 | * @param {...*} [partials] The arguments to be partially applied. |
||
7651 | * @returns {Function} Returns the new bound function. |
||
7652 | * @example |
||
7653 | * |
||
7654 | * var object = { |
||
7655 | * 'user': 'fred', |
||
7656 | * 'greet': function(greeting, punctuation) { |
||
7657 | * return greeting + ' ' + this.user + punctuation; |
||
7658 | * } |
||
7659 | * }; |
||
7660 | * |
||
7661 | * var bound = _.bindKey(object, 'greet', 'hi'); |
||
7662 | * bound('!'); |
||
7663 | * // => 'hi fred!' |
||
7664 | * |
||
7665 | * object.greet = function(greeting, punctuation) { |
||
7666 | * return greeting + 'ya ' + this.user + punctuation; |
||
7667 | * }; |
||
7668 | * |
||
7669 | * bound('!'); |
||
7670 | * // => 'hiya fred!' |
||
7671 | * |
||
7672 | * // using placeholders |
||
7673 | * var bound = _.bindKey(object, 'greet', _, '!'); |
||
7674 | * bound('hi'); |
||
7675 | * // => 'hiya fred!' |
||
7676 | */ |
||
7677 | var bindKey = restParam(function(object, key, partials) { |
||
7678 | var bitmask = BIND_FLAG | BIND_KEY_FLAG; |
||
7679 | if (partials.length) { |
||
7680 | var holders = replaceHolders(partials, bindKey.placeholder); |
||
7681 | bitmask |= PARTIAL_FLAG; |
||
7682 | } |
||
7683 | return createWrapper(key, bitmask, object, partials, holders); |
||
7684 | }); |
||
7685 | |||
7686 | /** |
||
7687 | * Creates a function that accepts one or more arguments of `func` that when |
||
7688 | * called either invokes `func` returning its result, if all `func` arguments |
||
7689 | * have been provided, or returns a function that accepts one or more of the |
||
7690 | * remaining `func` arguments, and so on. The arity of `func` may be specified |
||
7691 | * if `func.length` is not sufficient. |
||
7692 | * |
||
7693 | * The `_.curry.placeholder` value, which defaults to `_` in monolithic builds, |
||
7694 | * may be used as a placeholder for provided arguments. |
||
7695 | * |
||
7696 | * **Note:** This method does not set the "length" property of curried functions. |
||
7697 | * |
||
7698 | * @static |
||
7699 | * @memberOf _ |
||
7700 | * @category Function |
||
7701 | * @param {Function} func The function to curry. |
||
7702 | * @param {number} [arity=func.length] The arity of `func`. |
||
7703 | * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. |
||
7704 | * @returns {Function} Returns the new curried function. |
||
7705 | * @example |
||
7706 | * |
||
7707 | * var abc = function(a, b, c) { |
||
7708 | * return [a, b, c]; |
||
7709 | * }; |
||
7710 | * |
||
7711 | * var curried = _.curry(abc); |
||
7712 | * |
||
7713 | * curried(1)(2)(3); |
||
7714 | * // => [1, 2, 3] |
||
7715 | * |
||
7716 | * curried(1, 2)(3); |
||
7717 | * // => [1, 2, 3] |
||
7718 | * |
||
7719 | * curried(1, 2, 3); |
||
7720 | * // => [1, 2, 3] |
||
7721 | * |
||
7722 | * // using placeholders |
||
7723 | * curried(1)(_, 3)(2); |
||
7724 | * // => [1, 2, 3] |
||
7725 | */ |
||
7726 | var curry = createCurry(CURRY_FLAG); |
||
7727 | |||
7728 | /** |
||
7729 | * This method is like `_.curry` except that arguments are applied to `func` |
||
7730 | * in the manner of `_.partialRight` instead of `_.partial`. |
||
7731 | * |
||
7732 | * The `_.curryRight.placeholder` value, which defaults to `_` in monolithic |
||
7733 | * builds, may be used as a placeholder for provided arguments. |
||
7734 | * |
||
7735 | * **Note:** This method does not set the "length" property of curried functions. |
||
7736 | * |
||
7737 | * @static |
||
7738 | * @memberOf _ |
||
7739 | * @category Function |
||
7740 | * @param {Function} func The function to curry. |
||
7741 | * @param {number} [arity=func.length] The arity of `func`. |
||
7742 | * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. |
||
7743 | * @returns {Function} Returns the new curried function. |
||
7744 | * @example |
||
7745 | * |
||
7746 | * var abc = function(a, b, c) { |
||
7747 | * return [a, b, c]; |
||
7748 | * }; |
||
7749 | * |
||
7750 | * var curried = _.curryRight(abc); |
||
7751 | * |
||
7752 | * curried(3)(2)(1); |
||
7753 | * // => [1, 2, 3] |
||
7754 | * |
||
7755 | * curried(2, 3)(1); |
||
7756 | * // => [1, 2, 3] |
||
7757 | * |
||
7758 | * curried(1, 2, 3); |
||
7759 | * // => [1, 2, 3] |
||
7760 | * |
||
7761 | * // using placeholders |
||
7762 | * curried(3)(1, _)(2); |
||
7763 | * // => [1, 2, 3] |
||
7764 | */ |
||
7765 | var curryRight = createCurry(CURRY_RIGHT_FLAG); |
||
7766 | |||
7767 | /** |
||
7768 | * Creates a debounced function that delays invoking `func` until after `wait` |
||
7769 | * milliseconds have elapsed since the last time the debounced function was |
||
7770 | * invoked. The debounced function comes with a `cancel` method to cancel |
||
7771 | * delayed invocations. Provide an options object to indicate that `func` |
||
7772 | * should be invoked on the leading and/or trailing edge of the `wait` timeout. |
||
7773 | * Subsequent calls to the debounced function return the result of the last |
||
7774 | * `func` invocation. |
||
7775 | * |
||
7776 | * **Note:** If `leading` and `trailing` options are `true`, `func` is invoked |
||
7777 | * on the trailing edge of the timeout only if the the debounced function is |
||
7778 | * invoked more than once during the `wait` timeout. |
||
7779 | * |
||
7780 | * See [David Corbacho's article](http://drupalmotion.com/article/debounce-and-throttle-visual-explanation) |
||
7781 | * for details over the differences between `_.debounce` and `_.throttle`. |
||
7782 | * |
||
7783 | * @static |
||
7784 | * @memberOf _ |
||
7785 | * @category Function |
||
7786 | * @param {Function} func The function to debounce. |
||
7787 | * @param {number} [wait=0] The number of milliseconds to delay. |
||
7788 | * @param {Object} [options] The options object. |
||
7789 | * @param {boolean} [options.leading=false] Specify invoking on the leading |
||
7790 | * edge of the timeout. |
||
7791 | * @param {number} [options.maxWait] The maximum time `func` is allowed to be |
||
7792 | * delayed before it's invoked. |
||
7793 | * @param {boolean} [options.trailing=true] Specify invoking on the trailing |
||
7794 | * edge of the timeout. |
||
7795 | * @returns {Function} Returns the new debounced function. |
||
7796 | * @example |
||
7797 | * |
||
7798 | * // avoid costly calculations while the window size is in flux |
||
7799 | * jQuery(window).on('resize', _.debounce(calculateLayout, 150)); |
||
7800 | * |
||
7801 | * // invoke `sendMail` when the click event is fired, debouncing subsequent calls |
||
7802 | * jQuery('#postbox').on('click', _.debounce(sendMail, 300, { |
||
7803 | * 'leading': true, |
||
7804 | * 'trailing': false |
||
7805 | * })); |
||
7806 | * |
||
7807 | * // ensure `batchLog` is invoked once after 1 second of debounced calls |
||
7808 | * var source = new EventSource('/stream'); |
||
7809 | * jQuery(source).on('message', _.debounce(batchLog, 250, { |
||
7810 | * 'maxWait': 1000 |
||
7811 | * })); |
||
7812 | * |
||
7813 | * // cancel a debounced call |
||
7814 | * var todoChanges = _.debounce(batchLog, 1000); |
||
7815 | * Object.observe(models.todo, todoChanges); |
||
7816 | * |
||
7817 | * Object.observe(models, function(changes) { |
||
7818 | * if (_.find(changes, { 'user': 'todo', 'type': 'delete'})) { |
||
7819 | * todoChanges.cancel(); |
||
7820 | * } |
||
7821 | * }, ['delete']); |
||
7822 | * |
||
7823 | * // ...at some point `models.todo` is changed |
||
7824 | * models.todo.completed = true; |
||
7825 | * |
||
7826 | * // ...before 1 second has passed `models.todo` is deleted |
||
7827 | * // which cancels the debounced `todoChanges` call |
||
7828 | * delete models.todo; |
||
7829 | */ |
||
7830 | function debounce(func, wait, options) { |
||
7831 | var args, |
||
7832 | maxTimeoutId, |
||
7833 | result, |
||
7834 | stamp, |
||
7835 | thisArg, |
||
7836 | timeoutId, |
||
7837 | trailingCall, |
||
7838 | lastCalled = 0, |
||
7839 | maxWait = false, |
||
7840 | trailing = true; |
||
7841 | |||
7842 | if (typeof func != 'function') { |
||
7843 | throw new TypeError(FUNC_ERROR_TEXT); |
||
7844 | } |
||
7845 | wait = wait < 0 ? 0 : (+wait || 0); |
||
7846 | if (options === true) { |
||
7847 | var leading = true; |
||
7848 | trailing = false; |
||
7849 | } else if (isObject(options)) { |
||
7850 | leading = !!options.leading; |
||
7851 | maxWait = 'maxWait' in options && nativeMax(+options.maxWait || 0, wait); |
||
7852 | trailing = 'trailing' in options ? !!options.trailing : trailing; |
||
7853 | } |
||
7854 | |||
7855 | function cancel() { |
||
7856 | if (timeoutId) { |
||
7857 | clearTimeout(timeoutId); |
||
7858 | } |
||
7859 | if (maxTimeoutId) { |
||
7860 | clearTimeout(maxTimeoutId); |
||
7861 | } |
||
7862 | lastCalled = 0; |
||
7863 | maxTimeoutId = timeoutId = trailingCall = undefined; |
||
7864 | } |
||
7865 | |||
7866 | function complete(isCalled, id) { |
||
7867 | if (id) { |
||
7868 | clearTimeout(id); |
||
7869 | } |
||
7870 | maxTimeoutId = timeoutId = trailingCall = undefined; |
||
7871 | if (isCalled) { |
||
7872 | lastCalled = now(); |
||
7873 | result = func.apply(thisArg, args); |
||
7874 | if (!timeoutId && !maxTimeoutId) { |
||
7875 | args = thisArg = undefined; |
||
7876 | } |
||
7877 | } |
||
7878 | } |
||
7879 | |||
7880 | function delayed() { |
||
7881 | var remaining = wait - (now() - stamp); |
||
7882 | if (remaining <= 0 || remaining > wait) { |
||
7883 | complete(trailingCall, maxTimeoutId); |
||
7884 | } else { |
||
7885 | timeoutId = setTimeout(delayed, remaining); |
||
7886 | } |
||
7887 | } |
||
7888 | |||
7889 | function maxDelayed() { |
||
7890 | complete(trailing, timeoutId); |
||
7891 | } |
||
7892 | |||
7893 | function debounced() { |
||
7894 | args = arguments; |
||
7895 | stamp = now(); |
||
7896 | thisArg = this; |
||
7897 | trailingCall = trailing && (timeoutId || !leading); |
||
7898 | |||
7899 | if (maxWait === false) { |
||
7900 | var leadingCall = leading && !timeoutId; |
||
7901 | } else { |
||
7902 | if (!maxTimeoutId && !leading) { |
||
7903 | lastCalled = stamp; |
||
7904 | } |
||
7905 | var remaining = maxWait - (stamp - lastCalled), |
||
7906 | isCalled = remaining <= 0 || remaining > maxWait; |
||
7907 | |||
7908 | if (isCalled) { |
||
7909 | if (maxTimeoutId) { |
||
7910 | maxTimeoutId = clearTimeout(maxTimeoutId); |
||
7911 | } |
||
7912 | lastCalled = stamp; |
||
7913 | result = func.apply(thisArg, args); |
||
7914 | } |
||
7915 | else if (!maxTimeoutId) { |
||
7916 | maxTimeoutId = setTimeout(maxDelayed, remaining); |
||
7917 | } |
||
7918 | } |
||
7919 | if (isCalled && timeoutId) { |
||
7920 | timeoutId = clearTimeout(timeoutId); |
||
7921 | } |
||
7922 | else if (!timeoutId && wait !== maxWait) { |
||
7923 | timeoutId = setTimeout(delayed, wait); |
||
7924 | } |
||
7925 | if (leadingCall) { |
||
7926 | isCalled = true; |
||
7927 | result = func.apply(thisArg, args); |
||
7928 | } |
||
7929 | if (isCalled && !timeoutId && !maxTimeoutId) { |
||
7930 | args = thisArg = undefined; |
||
7931 | } |
||
7932 | return result; |
||
7933 | } |
||
7934 | debounced.cancel = cancel; |
||
7935 | return debounced; |
||
7936 | } |
||
7937 | |||
7938 | /** |
||
7939 | * Defers invoking the `func` until the current call stack has cleared. Any |
||
7940 | * additional arguments are provided to `func` when it's invoked. |
||
7941 | * |
||
7942 | * @static |
||
7943 | * @memberOf _ |
||
7944 | * @category Function |
||
7945 | * @param {Function} func The function to defer. |
||
7946 | * @param {...*} [args] The arguments to invoke the function with. |
||
7947 | * @returns {number} Returns the timer id. |
||
7948 | * @example |
||
7949 | * |
||
7950 | * _.defer(function(text) { |
||
7951 | * console.log(text); |
||
7952 | * }, 'deferred'); |
||
7953 | * // logs 'deferred' after one or more milliseconds |
||
7954 | */ |
||
7955 | var defer = restParam(function(func, args) { |
||
7956 | return baseDelay(func, 1, args); |
||
7957 | }); |
||
7958 | |||
7959 | /** |
||
7960 | * Invokes `func` after `wait` milliseconds. Any additional arguments are |
||
7961 | * provided to `func` when it's invoked. |
||
7962 | * |
||
7963 | * @static |
||
7964 | * @memberOf _ |
||
7965 | * @category Function |
||
7966 | * @param {Function} func The function to delay. |
||
7967 | * @param {number} wait The number of milliseconds to delay invocation. |
||
7968 | * @param {...*} [args] The arguments to invoke the function with. |
||
7969 | * @returns {number} Returns the timer id. |
||
7970 | * @example |
||
7971 | * |
||
7972 | * _.delay(function(text) { |
||
7973 | * console.log(text); |
||
7974 | * }, 1000, 'later'); |
||
7975 | * // => logs 'later' after one second |
||
7976 | */ |
||
7977 | var delay = restParam(function(func, wait, args) { |
||
7978 | return baseDelay(func, wait, args); |
||
7979 | }); |
||
7980 | |||
7981 | /** |
||
7982 | * Creates a function that returns the result of invoking the provided |
||
7983 | * functions with the `this` binding of the created function, where each |
||
7984 | * successive invocation is supplied the return value of the previous. |
||
7985 | * |
||
7986 | * @static |
||
7987 | * @memberOf _ |
||
7988 | * @category Function |
||
7989 | * @param {...Function} [funcs] Functions to invoke. |
||
7990 | * @returns {Function} Returns the new function. |
||
7991 | * @example |
||
7992 | * |
||
7993 | * function square(n) { |
||
7994 | * return n * n; |
||
7995 | * } |
||
7996 | * |
||
7997 | * var addSquare = _.flow(_.add, square); |
||
7998 | * addSquare(1, 2); |
||
7999 | * // => 9 |
||
8000 | */ |
||
8001 | var flow = createFlow(); |
||
8002 | |||
8003 | /** |
||
8004 | * This method is like `_.flow` except that it creates a function that |
||
8005 | * invokes the provided functions from right to left. |
||
8006 | * |
||
8007 | * @static |
||
8008 | * @memberOf _ |
||
8009 | * @alias backflow, compose |
||
8010 | * @category Function |
||
8011 | * @param {...Function} [funcs] Functions to invoke. |
||
8012 | * @returns {Function} Returns the new function. |
||
8013 | * @example |
||
8014 | * |
||
8015 | * function square(n) { |
||
8016 | * return n * n; |
||
8017 | * } |
||
8018 | * |
||
8019 | * var addSquare = _.flowRight(square, _.add); |
||
8020 | * addSquare(1, 2); |
||
8021 | * // => 9 |
||
8022 | */ |
||
8023 | var flowRight = createFlow(true); |
||
8024 | |||
8025 | /** |
||
8026 | * Creates a function that memoizes the result of `func`. If `resolver` is |
||
8027 | * provided it determines the cache key for storing the result based on the |
||
8028 | * arguments provided to the memoized function. By default, the first argument |
||
8029 | * provided to the memoized function is coerced to a string and used as the |
||
8030 | * cache key. The `func` is invoked with the `this` binding of the memoized |
||
8031 | * function. |
||
8032 | * |
||
8033 | * **Note:** The cache is exposed as the `cache` property on the memoized |
||
8034 | * function. Its creation may be customized by replacing the `_.memoize.Cache` |
||
8035 | * constructor with one whose instances implement the [`Map`](http://ecma-international.org/ecma-262/6.0/#sec-properties-of-the-map-prototype-object) |
||
8036 | * method interface of `get`, `has`, and `set`. |
||
8037 | * |
||
8038 | * @static |
||
8039 | * @memberOf _ |
||
8040 | * @category Function |
||
8041 | * @param {Function} func The function to have its output memoized. |
||
8042 | * @param {Function} [resolver] The function to resolve the cache key. |
||
8043 | * @returns {Function} Returns the new memoizing function. |
||
8044 | * @example |
||
8045 | * |
||
8046 | * var upperCase = _.memoize(function(string) { |
||
8047 | * return string.toUpperCase(); |
||
8048 | * }); |
||
8049 | * |
||
8050 | * upperCase('fred'); |
||
8051 | * // => 'FRED' |
||
8052 | * |
||
8053 | * // modifying the result cache |
||
8054 | * upperCase.cache.set('fred', 'BARNEY'); |
||
8055 | * upperCase('fred'); |
||
8056 | * // => 'BARNEY' |
||
8057 | * |
||
8058 | * // replacing `_.memoize.Cache` |
||
8059 | * var object = { 'user': 'fred' }; |
||
8060 | * var other = { 'user': 'barney' }; |
||
8061 | * var identity = _.memoize(_.identity); |
||
8062 | * |
||
8063 | * identity(object); |
||
8064 | * // => { 'user': 'fred' } |
||
8065 | * identity(other); |
||
8066 | * // => { 'user': 'fred' } |
||
8067 | * |
||
8068 | * _.memoize.Cache = WeakMap; |
||
8069 | * var identity = _.memoize(_.identity); |
||
8070 | * |
||
8071 | * identity(object); |
||
8072 | * // => { 'user': 'fred' } |
||
8073 | * identity(other); |
||
8074 | * // => { 'user': 'barney' } |
||
8075 | */ |
||
8076 | function memoize(func, resolver) { |
||
8077 | if (typeof func != 'function' || (resolver && typeof resolver != 'function')) { |
||
8078 | throw new TypeError(FUNC_ERROR_TEXT); |
||
8079 | } |
||
8080 | var memoized = function() { |
||
8081 | var args = arguments, |
||
8082 | key = resolver ? resolver.apply(this, args) : args[0], |
||
8083 | cache = memoized.cache; |
||
8084 | |||
8085 | if (cache.has(key)) { |
||
8086 | return cache.get(key); |
||
8087 | } |
||
8088 | var result = func.apply(this, args); |
||
8089 | memoized.cache = cache.set(key, result); |
||
8090 | return result; |
||
8091 | }; |
||
8092 | memoized.cache = new memoize.Cache; |
||
8093 | return memoized; |
||
8094 | } |
||
8095 | |||
8096 | /** |
||
8097 | * Creates a function that runs each argument through a corresponding |
||
8098 | * transform function. |
||
8099 | * |
||
8100 | * @static |
||
8101 | * @memberOf _ |
||
8102 | * @category Function |
||
8103 | * @param {Function} func The function to wrap. |
||
8104 | * @param {...(Function|Function[])} [transforms] The functions to transform |
||
8105 | * arguments, specified as individual functions or arrays of functions. |
||
8106 | * @returns {Function} Returns the new function. |
||
8107 | * @example |
||
8108 | * |
||
8109 | * function doubled(n) { |
||
8110 | * return n * 2; |
||
8111 | * } |
||
8112 | * |
||
8113 | * function square(n) { |
||
8114 | * return n * n; |
||
8115 | * } |
||
8116 | * |
||
8117 | * var modded = _.modArgs(function(x, y) { |
||
8118 | * return [x, y]; |
||
8119 | * }, square, doubled); |
||
8120 | * |
||
8121 | * modded(1, 2); |
||
8122 | * // => [1, 4] |
||
8123 | * |
||
8124 | * modded(5, 10); |
||
8125 | * // => [25, 20] |
||
8126 | */ |
||
8127 | var modArgs = restParam(function(func, transforms) { |
||
8128 | transforms = baseFlatten(transforms); |
||
8129 | if (typeof func != 'function' || !arrayEvery(transforms, baseIsFunction)) { |
||
8130 | throw new TypeError(FUNC_ERROR_TEXT); |
||
8131 | } |
||
8132 | var length = transforms.length; |
||
8133 | return restParam(function(args) { |
||
8134 | var index = nativeMin(args.length, length); |
||
8135 | while (index--) { |
||
8136 | args[index] = transforms[index](args[index]); |
||
8137 | } |
||
8138 | return func.apply(this, args); |
||
8139 | }); |
||
8140 | }); |
||
8141 | |||
8142 | /** |
||
8143 | * Creates a function that negates the result of the predicate `func`. The |
||
8144 | * `func` predicate is invoked with the `this` binding and arguments of the |
||
8145 | * created function. |
||
8146 | * |
||
8147 | * @static |
||
8148 | * @memberOf _ |
||
8149 | * @category Function |
||
8150 | * @param {Function} predicate The predicate to negate. |
||
8151 | * @returns {Function} Returns the new function. |
||
8152 | * @example |
||
8153 | * |
||
8154 | * function isEven(n) { |
||
8155 | * return n % 2 == 0; |
||
8156 | * } |
||
8157 | * |
||
8158 | * _.filter([1, 2, 3, 4, 5, 6], _.negate(isEven)); |
||
8159 | * // => [1, 3, 5] |
||
8160 | */ |
||
8161 | function negate(predicate) { |
||
8162 | if (typeof predicate != 'function') { |
||
8163 | throw new TypeError(FUNC_ERROR_TEXT); |
||
8164 | } |
||
8165 | return function() { |
||
8166 | return !predicate.apply(this, arguments); |
||
8167 | }; |
||
8168 | } |
||
8169 | |||
8170 | /** |
||
8171 | * Creates a function that is restricted to invoking `func` once. Repeat calls |
||
8172 | * to the function return the value of the first call. The `func` is invoked |
||
8173 | * with the `this` binding and arguments of the created function. |
||
8174 | * |
||
8175 | * @static |
||
8176 | * @memberOf _ |
||
8177 | * @category Function |
||
8178 | * @param {Function} func The function to restrict. |
||
8179 | * @returns {Function} Returns the new restricted function. |
||
8180 | * @example |
||
8181 | * |
||
8182 | * var initialize = _.once(createApplication); |
||
8183 | * initialize(); |
||
8184 | * initialize(); |
||
8185 | * // `initialize` invokes `createApplication` once |
||
8186 | */ |
||
8187 | function once(func) { |
||
8188 | return before(2, func); |
||
8189 | } |
||
8190 | |||
8191 | /** |
||
8192 | * Creates a function that invokes `func` with `partial` arguments prepended |
||
8193 | * to those provided to the new function. This method is like `_.bind` except |
||
8194 | * it does **not** alter the `this` binding. |
||
8195 | * |
||
8196 | * The `_.partial.placeholder` value, which defaults to `_` in monolithic |
||
8197 | * builds, may be used as a placeholder for partially applied arguments. |
||
8198 | * |
||
8199 | * **Note:** This method does not set the "length" property of partially |
||
8200 | * applied functions. |
||
8201 | * |
||
8202 | * @static |
||
8203 | * @memberOf _ |
||
8204 | * @category Function |
||
8205 | * @param {Function} func The function to partially apply arguments to. |
||
8206 | * @param {...*} [partials] The arguments to be partially applied. |
||
8207 | * @returns {Function} Returns the new partially applied function. |
||
8208 | * @example |
||
8209 | * |
||
8210 | * var greet = function(greeting, name) { |
||
8211 | * return greeting + ' ' + name; |
||
8212 | * }; |
||
8213 | * |
||
8214 | * var sayHelloTo = _.partial(greet, 'hello'); |
||
8215 | * sayHelloTo('fred'); |
||
8216 | * // => 'hello fred' |
||
8217 | * |
||
8218 | * // using placeholders |
||
8219 | * var greetFred = _.partial(greet, _, 'fred'); |
||
8220 | * greetFred('hi'); |
||
8221 | * // => 'hi fred' |
||
8222 | */ |
||
8223 | var partial = createPartial(PARTIAL_FLAG); |
||
8224 | |||
8225 | /** |
||
8226 | * This method is like `_.partial` except that partially applied arguments |
||
8227 | * are appended to those provided to the new function. |
||
8228 | * |
||
8229 | * The `_.partialRight.placeholder` value, which defaults to `_` in monolithic |
||
8230 | * builds, may be used as a placeholder for partially applied arguments. |
||
8231 | * |
||
8232 | * **Note:** This method does not set the "length" property of partially |
||
8233 | * applied functions. |
||
8234 | * |
||
8235 | * @static |
||
8236 | * @memberOf _ |
||
8237 | * @category Function |
||
8238 | * @param {Function} func The function to partially apply arguments to. |
||
8239 | * @param {...*} [partials] The arguments to be partially applied. |
||
8240 | * @returns {Function} Returns the new partially applied function. |
||
8241 | * @example |
||
8242 | * |
||
8243 | * var greet = function(greeting, name) { |
||
8244 | * return greeting + ' ' + name; |
||
8245 | * }; |
||
8246 | * |
||
8247 | * var greetFred = _.partialRight(greet, 'fred'); |
||
8248 | * greetFred('hi'); |
||
8249 | * // => 'hi fred' |
||
8250 | * |
||
8251 | * // using placeholders |
||
8252 | * var sayHelloTo = _.partialRight(greet, 'hello', _); |
||
8253 | * sayHelloTo('fred'); |
||
8254 | * // => 'hello fred' |
||
8255 | */ |
||
8256 | var partialRight = createPartial(PARTIAL_RIGHT_FLAG); |
||
8257 | |||
8258 | /** |
||
8259 | * Creates a function that invokes `func` with arguments arranged according |
||
8260 | * to the specified indexes where the argument value at the first index is |
||
8261 | * provided as the first argument, the argument value at the second index is |
||
8262 | * provided as the second argument, and so on. |
||
8263 | * |
||
8264 | * @static |
||
8265 | * @memberOf _ |
||
8266 | * @category Function |
||
8267 | * @param {Function} func The function to rearrange arguments for. |
||
8268 | * @param {...(number|number[])} indexes The arranged argument indexes, |
||
8269 | * specified as individual indexes or arrays of indexes. |
||
8270 | * @returns {Function} Returns the new function. |
||
8271 | * @example |
||
8272 | * |
||
8273 | * var rearged = _.rearg(function(a, b, c) { |
||
8274 | * return [a, b, c]; |
||
8275 | * }, 2, 0, 1); |
||
8276 | * |
||
8277 | * rearged('b', 'c', 'a') |
||
8278 | * // => ['a', 'b', 'c'] |
||
8279 | * |
||
8280 | * var map = _.rearg(_.map, [1, 0]); |
||
8281 | * map(function(n) { |
||
8282 | * return n * 3; |
||
8283 | * }, [1, 2, 3]); |
||
8284 | * // => [3, 6, 9] |
||
8285 | */ |
||
8286 | var rearg = restParam(function(func, indexes) { |
||
8287 | return createWrapper(func, REARG_FLAG, undefined, undefined, undefined, baseFlatten(indexes)); |
||
8288 | }); |
||
8289 | |||
8290 | /** |
||
8291 | * Creates a function that invokes `func` with the `this` binding of the |
||
8292 | * created function and arguments from `start` and beyond provided as an array. |
||
8293 | * |
||
8294 | * **Note:** This method is based on the [rest parameter](https://developer.mozilla.org/Web/JavaScript/Reference/Functions/rest_parameters). |
||
8295 | * |
||
8296 | * @static |
||
8297 | * @memberOf _ |
||
8298 | * @category Function |
||
8299 | * @param {Function} func The function to apply a rest parameter to. |
||
8300 | * @param {number} [start=func.length-1] The start position of the rest parameter. |
||
8301 | * @returns {Function} Returns the new function. |
||
8302 | * @example |
||
8303 | * |
||
8304 | * var say = _.restParam(function(what, names) { |
||
8305 | * return what + ' ' + _.initial(names).join(', ') + |
||
8306 | * (_.size(names) > 1 ? ', & ' : '') + _.last(names); |
||
8307 | * }); |
||
8308 | * |
||
8309 | * say('hello', 'fred', 'barney', 'pebbles'); |
||
8310 | * // => 'hello fred, barney, & pebbles' |
||
8311 | */ |
||
8312 | function restParam(func, start) { |
||
8313 | if (typeof func != 'function') { |
||
8314 | throw new TypeError(FUNC_ERROR_TEXT); |
||
8315 | } |
||
8316 | start = nativeMax(start === undefined ? (func.length - 1) : (+start || 0), 0); |
||
8317 | return function() { |
||
8318 | var args = arguments, |
||
8319 | index = -1, |
||
8320 | length = nativeMax(args.length - start, 0), |
||
8321 | rest = Array(length); |
||
8322 | |||
8323 | while (++index < length) { |
||
8324 | rest[index] = args[start + index]; |
||
8325 | } |
||
8326 | switch (start) { |
||
8327 | case 0: return func.call(this, rest); |
||
8328 | case 1: return func.call(this, args[0], rest); |
||
8329 | case 2: return func.call(this, args[0], args[1], rest); |
||
8330 | } |
||
8331 | var otherArgs = Array(start + 1); |
||
8332 | index = -1; |
||
8333 | while (++index < start) { |
||
8334 | otherArgs[index] = args[index]; |
||
8335 | } |
||
8336 | otherArgs[start] = rest; |
||
8337 | return func.apply(this, otherArgs); |
||
8338 | }; |
||
8339 | } |
||
8340 | |||
8341 | /** |
||
8342 | * Creates a function that invokes `func` with the `this` binding of the created |
||
8343 | * function and an array of arguments much like [`Function#apply`](https://es5.github.io/#x15.3.4.3). |
||
8344 | * |
||
8345 | * **Note:** This method is based on the [spread operator](https://developer.mozilla.org/Web/JavaScript/Reference/Operators/Spread_operator). |
||
8346 | * |
||
8347 | * @static |
||
8348 | * @memberOf _ |
||
8349 | * @category Function |
||
8350 | * @param {Function} func The function to spread arguments over. |
||
8351 | * @returns {Function} Returns the new function. |
||
8352 | * @example |
||
8353 | * |
||
8354 | * var say = _.spread(function(who, what) { |
||
8355 | * return who + ' says ' + what; |
||
8356 | * }); |
||
8357 | * |
||
8358 | * say(['fred', 'hello']); |
||
8359 | * // => 'fred says hello' |
||
8360 | * |
||
8361 | * // with a Promise |
||
8362 | * var numbers = Promise.all([ |
||
8363 | * Promise.resolve(40), |
||
8364 | * Promise.resolve(36) |
||
8365 | * ]); |
||
8366 | * |
||
8367 | * numbers.then(_.spread(function(x, y) { |
||
8368 | * return x + y; |
||
8369 | * })); |
||
8370 | * // => a Promise of 76 |
||
8371 | */ |
||
8372 | function spread(func) { |
||
8373 | if (typeof func != 'function') { |
||
8374 | throw new TypeError(FUNC_ERROR_TEXT); |
||
8375 | } |
||
8376 | return function(array) { |
||
8377 | return func.apply(this, array); |
||
8378 | }; |
||
8379 | } |
||
8380 | |||
8381 | /** |
||
8382 | * Creates a throttled function that only invokes `func` at most once per |
||
8383 | * every `wait` milliseconds. The throttled function comes with a `cancel` |
||
8384 | * method to cancel delayed invocations. Provide an options object to indicate |
||
8385 | * that `func` should be invoked on the leading and/or trailing edge of the |
||
8386 | * `wait` timeout. Subsequent calls to the throttled function return the |
||
8387 | * result of the last `func` call. |
||
8388 | * |
||
8389 | * **Note:** If `leading` and `trailing` options are `true`, `func` is invoked |
||
8390 | * on the trailing edge of the timeout only if the the throttled function is |
||
8391 | * invoked more than once during the `wait` timeout. |
||
8392 | * |
||
8393 | * See [David Corbacho's article](http://drupalmotion.com/article/debounce-and-throttle-visual-explanation) |
||
8394 | * for details over the differences between `_.throttle` and `_.debounce`. |
||
8395 | * |
||
8396 | * @static |
||
8397 | * @memberOf _ |
||
8398 | * @category Function |
||
8399 | * @param {Function} func The function to throttle. |
||
8400 | * @param {number} [wait=0] The number of milliseconds to throttle invocations to. |
||
8401 | * @param {Object} [options] The options object. |
||
8402 | * @param {boolean} [options.leading=true] Specify invoking on the leading |
||
8403 | * edge of the timeout. |
||
8404 | * @param {boolean} [options.trailing=true] Specify invoking on the trailing |
||
8405 | * edge of the timeout. |
||
8406 | * @returns {Function} Returns the new throttled function. |
||
8407 | * @example |
||
8408 | * |
||
8409 | * // avoid excessively updating the position while scrolling |
||
8410 | * jQuery(window).on('scroll', _.throttle(updatePosition, 100)); |
||
8411 | * |
||
8412 | * // invoke `renewToken` when the click event is fired, but not more than once every 5 minutes |
||
8413 | * jQuery('.interactive').on('click', _.throttle(renewToken, 300000, { |
||
8414 | * 'trailing': false |
||
8415 | * })); |
||
8416 | * |
||
8417 | * // cancel a trailing throttled call |
||
8418 | * jQuery(window).on('popstate', throttled.cancel); |
||
8419 | */ |
||
8420 | function throttle(func, wait, options) { |
||
8421 | var leading = true, |
||
8422 | trailing = true; |
||
8423 | |||
8424 | if (typeof func != 'function') { |
||
8425 | throw new TypeError(FUNC_ERROR_TEXT); |
||
8426 | } |
||
8427 | if (options === false) { |
||
8428 | leading = false; |
||
8429 | } else if (isObject(options)) { |
||
8430 | leading = 'leading' in options ? !!options.leading : leading; |
||
8431 | trailing = 'trailing' in options ? !!options.trailing : trailing; |
||
8432 | } |
||
8433 | return debounce(func, wait, { 'leading': leading, 'maxWait': +wait, 'trailing': trailing }); |
||
8434 | } |
||
8435 | |||
8436 | /** |
||
8437 | * Creates a function that provides `value` to the wrapper function as its |
||
8438 | * first argument. Any additional arguments provided to the function are |
||
8439 | * appended to those provided to the wrapper function. The wrapper is invoked |
||
8440 | * with the `this` binding of the created function. |
||
8441 | * |
||
8442 | * @static |
||
8443 | * @memberOf _ |
||
8444 | * @category Function |
||
8445 | * @param {*} value The value to wrap. |
||
8446 | * @param {Function} wrapper The wrapper function. |
||
8447 | * @returns {Function} Returns the new function. |
||
8448 | * @example |
||
8449 | * |
||
8450 | * var p = _.wrap(_.escape, function(func, text) { |
||
8451 | * return '<p>' + func(text) + '</p>'; |
||
8452 | * }); |
||
8453 | * |
||
8454 | * p('fred, barney, & pebbles'); |
||
8455 | * // => '<p>fred, barney, & pebbles</p>' |
||
8456 | */ |
||
8457 | function wrap(value, wrapper) { |
||
8458 | wrapper = wrapper == null ? identity : wrapper; |
||
8459 | return createWrapper(wrapper, PARTIAL_FLAG, undefined, [value], []); |
||
8460 | } |
||
8461 | |||
8462 | /*------------------------------------------------------------------------*/ |
||
8463 | |||
8464 | /** |
||
8465 | * Creates a clone of `value`. If `isDeep` is `true` nested objects are cloned, |
||
8466 | * otherwise they are assigned by reference. If `customizer` is provided it's |
||
8467 | * invoked to produce the cloned values. If `customizer` returns `undefined` |
||
8468 | * cloning is handled by the method instead. The `customizer` is bound to |
||
8469 | * `thisArg` and invoked with up to three argument; (value [, index|key, object]). |
||
8470 | * |
||
8471 | * **Note:** This method is loosely based on the |
||
8472 | * [structured clone algorithm](http://www.w3.org/TR/html5/infrastructure.html#internal-structured-cloning-algorithm). |
||
8473 | * The enumerable properties of `arguments` objects and objects created by |
||
8474 | * constructors other than `Object` are cloned to plain `Object` objects. An |
||
8475 | * empty object is returned for uncloneable values such as functions, DOM nodes, |
||
8476 | * Maps, Sets, and WeakMaps. |
||
8477 | * |
||
8478 | * @static |
||
8479 | * @memberOf _ |
||
8480 | * @category Lang |
||
8481 | * @param {*} value The value to clone. |
||
8482 | * @param {boolean} [isDeep] Specify a deep clone. |
||
8483 | * @param {Function} [customizer] The function to customize cloning values. |
||
8484 | * @param {*} [thisArg] The `this` binding of `customizer`. |
||
8485 | * @returns {*} Returns the cloned value. |
||
8486 | * @example |
||
8487 | * |
||
8488 | * var users = [ |
||
8489 | * { 'user': 'barney' }, |
||
8490 | * { 'user': 'fred' } |
||
8491 | * ]; |
||
8492 | * |
||
8493 | * var shallow = _.clone(users); |
||
8494 | * shallow[0] === users[0]; |
||
8495 | * // => true |
||
8496 | * |
||
8497 | * var deep = _.clone(users, true); |
||
8498 | * deep[0] === users[0]; |
||
8499 | * // => false |
||
8500 | * |
||
8501 | * // using a customizer callback |
||
8502 | * var el = _.clone(document.body, function(value) { |
||
8503 | * if (_.isElement(value)) { |
||
8504 | * return value.cloneNode(false); |
||
8505 | * } |
||
8506 | * }); |
||
8507 | * |
||
8508 | * el === document.body |
||
8509 | * // => false |
||
8510 | * el.nodeName |
||
8511 | * // => BODY |
||
8512 | * el.childNodes.length; |
||
8513 | * // => 0 |
||
8514 | */ |
||
8515 | function clone(value, isDeep, customizer, thisArg) { |
||
8516 | if (isDeep && typeof isDeep != 'boolean' && isIterateeCall(value, isDeep, customizer)) { |
||
8517 | isDeep = false; |
||
8518 | } |
||
8519 | else if (typeof isDeep == 'function') { |
||
8520 | thisArg = customizer; |
||
8521 | customizer = isDeep; |
||
8522 | isDeep = false; |
||
8523 | } |
||
8524 | return typeof customizer == 'function' |
||
8525 | ? baseClone(value, isDeep, bindCallback(customizer, thisArg, 3)) |
||
8526 | : baseClone(value, isDeep); |
||
8527 | } |
||
8528 | |||
8529 | /** |
||
8530 | * Creates a deep clone of `value`. If `customizer` is provided it's invoked |
||
8531 | * to produce the cloned values. If `customizer` returns `undefined` cloning |
||
8532 | * is handled by the method instead. The `customizer` is bound to `thisArg` |
||
8533 | * and invoked with up to three argument; (value [, index|key, object]). |
||
8534 | * |
||
8535 | * **Note:** This method is loosely based on the |
||
8536 | * [structured clone algorithm](http://www.w3.org/TR/html5/infrastructure.html#internal-structured-cloning-algorithm). |
||
8537 | * The enumerable properties of `arguments` objects and objects created by |
||
8538 | * constructors other than `Object` are cloned to plain `Object` objects. An |
||
8539 | * empty object is returned for uncloneable values such as functions, DOM nodes, |
||
8540 | * Maps, Sets, and WeakMaps. |
||
8541 | * |
||
8542 | * @static |
||
8543 | * @memberOf _ |
||
8544 | * @category Lang |
||
8545 | * @param {*} value The value to deep clone. |
||
8546 | * @param {Function} [customizer] The function to customize cloning values. |
||
8547 | * @param {*} [thisArg] The `this` binding of `customizer`. |
||
8548 | * @returns {*} Returns the deep cloned value. |
||
8549 | * @example |
||
8550 | * |
||
8551 | * var users = [ |
||
8552 | * { 'user': 'barney' }, |
||
8553 | * { 'user': 'fred' } |
||
8554 | * ]; |
||
8555 | * |
||
8556 | * var deep = _.cloneDeep(users); |
||
8557 | * deep[0] === users[0]; |
||
8558 | * // => false |
||
8559 | * |
||
8560 | * // using a customizer callback |
||
8561 | * var el = _.cloneDeep(document.body, function(value) { |
||
8562 | * if (_.isElement(value)) { |
||
8563 | * return value.cloneNode(true); |
||
8564 | * } |
||
8565 | * }); |
||
8566 | * |
||
8567 | * el === document.body |
||
8568 | * // => false |
||
8569 | * el.nodeName |
||
8570 | * // => BODY |
||
8571 | * el.childNodes.length; |
||
8572 | * // => 20 |
||
8573 | */ |
||
8574 | function cloneDeep(value, customizer, thisArg) { |
||
8575 | return typeof customizer == 'function' |
||
8576 | ? baseClone(value, true, bindCallback(customizer, thisArg, 3)) |
||
8577 | : baseClone(value, true); |
||
8578 | } |
||
8579 | |||
8580 | /** |
||
8581 | * Checks if `value` is greater than `other`. |
||
8582 | * |
||
8583 | * @static |
||
8584 | * @memberOf _ |
||
8585 | * @category Lang |
||
8586 | * @param {*} value The value to compare. |
||
8587 | * @param {*} other The other value to compare. |
||
8588 | * @returns {boolean} Returns `true` if `value` is greater than `other`, else `false`. |
||
8589 | * @example |
||
8590 | * |
||
8591 | * _.gt(3, 1); |
||
8592 | * // => true |
||
8593 | * |
||
8594 | * _.gt(3, 3); |
||
8595 | * // => false |
||
8596 | * |
||
8597 | * _.gt(1, 3); |
||
8598 | * // => false |
||
8599 | */ |
||
8600 | function gt(value, other) { |
||
8601 | return value > other; |
||
8602 | } |
||
8603 | |||
8604 | /** |
||
8605 | * Checks if `value` is greater than or equal to `other`. |
||
8606 | * |
||
8607 | * @static |
||
8608 | * @memberOf _ |
||
8609 | * @category Lang |
||
8610 | * @param {*} value The value to compare. |
||
8611 | * @param {*} other The other value to compare. |
||
8612 | * @returns {boolean} Returns `true` if `value` is greater than or equal to `other`, else `false`. |
||
8613 | * @example |
||
8614 | * |
||
8615 | * _.gte(3, 1); |
||
8616 | * // => true |
||
8617 | * |
||
8618 | * _.gte(3, 3); |
||
8619 | * // => true |
||
8620 | * |
||
8621 | * _.gte(1, 3); |
||
8622 | * // => false |
||
8623 | */ |
||
8624 | function gte(value, other) { |
||
8625 | return value >= other; |
||
8626 | } |
||
8627 | |||
8628 | /** |
||
8629 | * Checks if `value` is classified as an `arguments` object. |
||
8630 | * |
||
8631 | * @static |
||
8632 | * @memberOf _ |
||
8633 | * @category Lang |
||
8634 | * @param {*} value The value to check. |
||
8635 | * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. |
||
8636 | * @example |
||
8637 | * |
||
8638 | * _.isArguments(function() { return arguments; }()); |
||
8639 | * // => true |
||
8640 | * |
||
8641 | * _.isArguments([1, 2, 3]); |
||
8642 | * // => false |
||
8643 | */ |
||
8644 | function isArguments(value) { |
||
8645 | return isObjectLike(value) && isArrayLike(value) && |
||
8646 | hasOwnProperty.call(value, 'callee') && !propertyIsEnumerable.call(value, 'callee'); |
||
8647 | } |
||
8648 | |||
8649 | /** |
||
8650 | * Checks if `value` is classified as an `Array` object. |
||
8651 | * |
||
8652 | * @static |
||
8653 | * @memberOf _ |
||
8654 | * @category Lang |
||
8655 | * @param {*} value The value to check. |
||
8656 | * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. |
||
8657 | * @example |
||
8658 | * |
||
8659 | * _.isArray([1, 2, 3]); |
||
8660 | * // => true |
||
8661 | * |
||
8662 | * _.isArray(function() { return arguments; }()); |
||
8663 | * // => false |
||
8664 | */ |
||
8665 | var isArray = nativeIsArray || function(value) { |
||
8666 | return isObjectLike(value) && isLength(value.length) && objToString.call(value) == arrayTag; |
||
8667 | }; |
||
8668 | |||
8669 | /** |
||
8670 | * Checks if `value` is classified as a boolean primitive or object. |
||
8671 | * |
||
8672 | * @static |
||
8673 | * @memberOf _ |
||
8674 | * @category Lang |
||
8675 | * @param {*} value The value to check. |
||
8676 | * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. |
||
8677 | * @example |
||
8678 | * |
||
8679 | * _.isBoolean(false); |
||
8680 | * // => true |
||
8681 | * |
||
8682 | * _.isBoolean(null); |
||
8683 | * // => false |
||
8684 | */ |
||
8685 | function isBoolean(value) { |
||
8686 | return value === true || value === false || (isObjectLike(value) && objToString.call(value) == boolTag); |
||
8687 | } |
||
8688 | |||
8689 | /** |
||
8690 | * Checks if `value` is classified as a `Date` object. |
||
8691 | * |
||
8692 | * @static |
||
8693 | * @memberOf _ |
||
8694 | * @category Lang |
||
8695 | * @param {*} value The value to check. |
||
8696 | * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. |
||
8697 | * @example |
||
8698 | * |
||
8699 | * _.isDate(new Date); |
||
8700 | * // => true |
||
8701 | * |
||
8702 | * _.isDate('Mon April 23 2012'); |
||
8703 | * // => false |
||
8704 | */ |
||
8705 | function isDate(value) { |
||
8706 | return isObjectLike(value) && objToString.call(value) == dateTag; |
||
8707 | } |
||
8708 | |||
8709 | /** |
||
8710 | * Checks if `value` is a DOM element. |
||
8711 | * |
||
8712 | * @static |
||
8713 | * @memberOf _ |
||
8714 | * @category Lang |
||
8715 | * @param {*} value The value to check. |
||
8716 | * @returns {boolean} Returns `true` if `value` is a DOM element, else `false`. |
||
8717 | * @example |
||
8718 | * |
||
8719 | * _.isElement(document.body); |
||
8720 | * // => true |
||
8721 | * |
||
8722 | * _.isElement('<body>'); |
||
8723 | * // => false |
||
8724 | */ |
||
8725 | function isElement(value) { |
||
8726 | return !!value && value.nodeType === 1 && isObjectLike(value) && !isPlainObject(value); |
||
8727 | } |
||
8728 | |||
8729 | /** |
||
8730 | * Checks if `value` is empty. A value is considered empty unless it's an |
||
8731 | * `arguments` object, array, string, or jQuery-like collection with a length |
||
8732 | * greater than `0` or an object with own enumerable properties. |
||
8733 | * |
||
8734 | * @static |
||
8735 | * @memberOf _ |
||
8736 | * @category Lang |
||
8737 | * @param {Array|Object|string} value The value to inspect. |
||
8738 | * @returns {boolean} Returns `true` if `value` is empty, else `false`. |
||
8739 | * @example |
||
8740 | * |
||
8741 | * _.isEmpty(null); |
||
8742 | * // => true |
||
8743 | * |
||
8744 | * _.isEmpty(true); |
||
8745 | * // => true |
||
8746 | * |
||
8747 | * _.isEmpty(1); |
||
8748 | * // => true |
||
8749 | * |
||
8750 | * _.isEmpty([1, 2, 3]); |
||
8751 | * // => false |
||
8752 | * |
||
8753 | * _.isEmpty({ 'a': 1 }); |
||
8754 | * // => false |
||
8755 | */ |
||
8756 | function isEmpty(value) { |
||
8757 | if (value == null) { |
||
8758 | return true; |
||
8759 | } |
||
8760 | if (isArrayLike(value) && (isArray(value) || isString(value) || isArguments(value) || |
||
8761 | (isObjectLike(value) && isFunction(value.splice)))) { |
||
8762 | return !value.length; |
||
8763 | } |
||
8764 | return !keys(value).length; |
||
8765 | } |
||
8766 | |||
8767 | /** |
||
8768 | * Performs a deep comparison between two values to determine if they are |
||
8769 | * equivalent. If `customizer` is provided it's invoked to compare values. |
||
8770 | * If `customizer` returns `undefined` comparisons are handled by the method |
||
8771 | * instead. The `customizer` is bound to `thisArg` and invoked with up to |
||
8772 | * three arguments: (value, other [, index|key]). |
||
8773 | * |
||
8774 | * **Note:** This method supports comparing arrays, booleans, `Date` objects, |
||
8775 | * numbers, `Object` objects, regexes, and strings. Objects are compared by |
||
8776 | * their own, not inherited, enumerable properties. Functions and DOM nodes |
||
8777 | * are **not** supported. Provide a customizer function to extend support |
||
8778 | * for comparing other values. |
||
8779 | * |
||
8780 | * @static |
||
8781 | * @memberOf _ |
||
8782 | * @alias eq |
||
8783 | * @category Lang |
||
8784 | * @param {*} value The value to compare. |
||
8785 | * @param {*} other The other value to compare. |
||
8786 | * @param {Function} [customizer] The function to customize value comparisons. |
||
8787 | * @param {*} [thisArg] The `this` binding of `customizer`. |
||
8788 | * @returns {boolean} Returns `true` if the values are equivalent, else `false`. |
||
8789 | * @example |
||
8790 | * |
||
8791 | * var object = { 'user': 'fred' }; |
||
8792 | * var other = { 'user': 'fred' }; |
||
8793 | * |
||
8794 | * object == other; |
||
8795 | * // => false |
||
8796 | * |
||
8797 | * _.isEqual(object, other); |
||
8798 | * // => true |
||
8799 | * |
||
8800 | * // using a customizer callback |
||
8801 | * var array = ['hello', 'goodbye']; |
||
8802 | * var other = ['hi', 'goodbye']; |
||
8803 | * |
||
8804 | * _.isEqual(array, other, function(value, other) { |
||
8805 | * if (_.every([value, other], RegExp.prototype.test, /^h(?:i|ello)$/)) { |
||
8806 | * return true; |
||
8807 | * } |
||
8808 | * }); |
||
8809 | * // => true |
||
8810 | */ |
||
8811 | function isEqual(value, other, customizer, thisArg) { |
||
8812 | customizer = typeof customizer == 'function' ? bindCallback(customizer, thisArg, 3) : undefined; |
||
8813 | var result = customizer ? customizer(value, other) : undefined; |
||
8814 | return result === undefined ? baseIsEqual(value, other, customizer) : !!result; |
||
8815 | } |
||
8816 | |||
8817 | /** |
||
8818 | * Checks if `value` is an `Error`, `EvalError`, `RangeError`, `ReferenceError`, |
||
8819 | * `SyntaxError`, `TypeError`, or `URIError` object. |
||
8820 | * |
||
8821 | * @static |
||
8822 | * @memberOf _ |
||
8823 | * @category Lang |
||
8824 | * @param {*} value The value to check. |
||
8825 | * @returns {boolean} Returns `true` if `value` is an error object, else `false`. |
||
8826 | * @example |
||
8827 | * |
||
8828 | * _.isError(new Error); |
||
8829 | * // => true |
||
8830 | * |
||
8831 | * _.isError(Error); |
||
8832 | * // => false |
||
8833 | */ |
||
8834 | function isError(value) { |
||
8835 | return isObjectLike(value) && typeof value.message == 'string' && objToString.call(value) == errorTag; |
||
8836 | } |
||
8837 | |||
8838 | /** |
||
8839 | * Checks if `value` is a finite primitive number. |
||
8840 | * |
||
8841 | * **Note:** This method is based on [`Number.isFinite`](http://ecma-international.org/ecma-262/6.0/#sec-number.isfinite). |
||
8842 | * |
||
8843 | * @static |
||
8844 | * @memberOf _ |
||
8845 | * @category Lang |
||
8846 | * @param {*} value The value to check. |
||
8847 | * @returns {boolean} Returns `true` if `value` is a finite number, else `false`. |
||
8848 | * @example |
||
8849 | * |
||
8850 | * _.isFinite(10); |
||
8851 | * // => true |
||
8852 | * |
||
8853 | * _.isFinite('10'); |
||
8854 | * // => false |
||
8855 | * |
||
8856 | * _.isFinite(true); |
||
8857 | * // => false |
||
8858 | * |
||
8859 | * _.isFinite(Object(10)); |
||
8860 | * // => false |
||
8861 | * |
||
8862 | * _.isFinite(Infinity); |
||
8863 | * // => false |
||
8864 | */ |
||
8865 | function isFinite(value) { |
||
8866 | return typeof value == 'number' && nativeIsFinite(value); |
||
8867 | } |
||
8868 | |||
8869 | /** |
||
8870 | * Checks if `value` is classified as a `Function` object. |
||
8871 | * |
||
8872 | * @static |
||
8873 | * @memberOf _ |
||
8874 | * @category Lang |
||
8875 | * @param {*} value The value to check. |
||
8876 | * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. |
||
8877 | * @example |
||
8878 | * |
||
8879 | * _.isFunction(_); |
||
8880 | * // => true |
||
8881 | * |
||
8882 | * _.isFunction(/abc/); |
||
8883 | * // => false |
||
8884 | */ |
||
8885 | function isFunction(value) { |
||
8886 | if (!isObject(value)) { |
||
8887 | return false; |
||
8888 | }//--• |
||
8889 | |||
8890 | // The use of `Object#toString` avoids issues with the `typeof` operator |
||
8891 | // in older versions of Chrome and Safari which return 'function' for regexes |
||
8892 | // and Safari 8 which returns 'object' for typed array constructors. |
||
8893 | var tag = objToString.call(value); |
||
8894 | |||
8895 | // Return true if this looks like a function, an "async function", a "generator", or a "proxy". |
||
8896 | return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag; |
||
8897 | |||
8898 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
||
8899 | // ^^^^ |
||
8900 | // PATCHED FROM https://github.com/lodash/lodash/commit/95bc54a3ddc7a25f5e134f5b376a0d1d96118f49 |
||
8901 | // Note that, in Lodash 4, this looks like: |
||
8902 | // ``` |
||
8903 | // return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag; |
||
8904 | // ``` |
||
8905 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
||
8906 | } |
||
8907 | |||
8908 | /** |
||
8909 | * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`. |
||
8910 | * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) |
||
8911 | * |
||
8912 | * @static |
||
8913 | * @memberOf _ |
||
8914 | * @category Lang |
||
8915 | * @param {*} value The value to check. |
||
8916 | * @returns {boolean} Returns `true` if `value` is an object, else `false`. |
||
8917 | * @example |
||
8918 | * |
||
8919 | * _.isObject({}); |
||
8920 | * // => true |
||
8921 | * |
||
8922 | * _.isObject([1, 2, 3]); |
||
8923 | * // => true |
||
8924 | * |
||
8925 | * _.isObject(1); |
||
8926 | * // => false |
||
8927 | */ |
||
8928 | function isObject(value) { |
||
8929 | // Avoid a V8 JIT bug in Chrome 19-20. |
||
8930 | // See https://code.google.com/p/v8/issues/detail?id=2291 for more details. |
||
8931 | var type = typeof value; |
||
8932 | return !!value && (type == 'object' || type == 'function'); |
||
8933 | } |
||
8934 | |||
8935 | /** |
||
8936 | * Performs a deep comparison between `object` and `source` to determine if |
||
8937 | * `object` contains equivalent property values. If `customizer` is provided |
||
8938 | * it's invoked to compare values. If `customizer` returns `undefined` |
||
8939 | * comparisons are handled by the method instead. The `customizer` is bound |
||
8940 | * to `thisArg` and invoked with three arguments: (value, other, index|key). |
||
8941 | * |
||
8942 | * **Note:** This method supports comparing properties of arrays, booleans, |
||
8943 | * `Date` objects, numbers, `Object` objects, regexes, and strings. Functions |
||
8944 | * and DOM nodes are **not** supported. Provide a customizer function to extend |
||
8945 | * support for comparing other values. |
||
8946 | * |
||
8947 | * @static |
||
8948 | * @memberOf _ |
||
8949 | * @category Lang |
||
8950 | * @param {Object} object The object to inspect. |
||
8951 | * @param {Object} source The object of property values to match. |
||
8952 | * @param {Function} [customizer] The function to customize value comparisons. |
||
8953 | * @param {*} [thisArg] The `this` binding of `customizer`. |
||
8954 | * @returns {boolean} Returns `true` if `object` is a match, else `false`. |
||
8955 | * @example |
||
8956 | * |
||
8957 | * var object = { 'user': 'fred', 'age': 40 }; |
||
8958 | * |
||
8959 | * _.isMatch(object, { 'age': 40 }); |
||
8960 | * // => true |
||
8961 | * |
||
8962 | * _.isMatch(object, { 'age': 36 }); |
||
8963 | * // => false |
||
8964 | * |
||
8965 | * // using a customizer callback |
||
8966 | * var object = { 'greeting': 'hello' }; |
||
8967 | * var source = { 'greeting': 'hi' }; |
||
8968 | * |
||
8969 | * _.isMatch(object, source, function(value, other) { |
||
8970 | * return _.every([value, other], RegExp.prototype.test, /^h(?:i|ello)$/) || undefined; |
||
8971 | * }); |
||
8972 | * // => true |
||
8973 | */ |
||
8974 | function isMatch(object, source, customizer, thisArg) { |
||
8975 | customizer = typeof customizer == 'function' ? bindCallback(customizer, thisArg, 3) : undefined; |
||
8976 | return baseIsMatch(object, getMatchData(source), customizer); |
||
8977 | } |
||
8978 | |||
8979 | /** |
||
8980 | * Checks if `value` is `NaN`. |
||
8981 | * |
||
8982 | * **Note:** This method is not the same as [`isNaN`](https://es5.github.io/#x15.1.2.4) |
||
8983 | * which returns `true` for `undefined` and other non-numeric values. |
||
8984 | * |
||
8985 | * @static |
||
8986 | * @memberOf _ |
||
8987 | * @category Lang |
||
8988 | * @param {*} value The value to check. |
||
8989 | * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`. |
||
8990 | * @example |
||
8991 | * |
||
8992 | * _.isNaN(NaN); |
||
8993 | * // => true |
||
8994 | * |
||
8995 | * _.isNaN(new Number(NaN)); |
||
8996 | * // => true |
||
8997 | * |
||
8998 | * isNaN(undefined); |
||
8999 | * // => true |
||
9000 | * |
||
9001 | * _.isNaN(undefined); |
||
9002 | * // => false |
||
9003 | */ |
||
9004 | function isNaN(value) { |
||
9005 | // An `NaN` primitive is the only value that is not equal to itself. |
||
9006 | // Perform the `toStringTag` check first to avoid errors with some host objects in IE. |
||
9007 | return isNumber(value) && value != +value; |
||
9008 | } |
||
9009 | |||
9010 | /** |
||
9011 | * Checks if `value` is a native function. |
||
9012 | * |
||
9013 | * @static |
||
9014 | * @memberOf _ |
||
9015 | * @category Lang |
||
9016 | * @param {*} value The value to check. |
||
9017 | * @returns {boolean} Returns `true` if `value` is a native function, else `false`. |
||
9018 | * @example |
||
9019 | * |
||
9020 | * _.isNative(Array.prototype.push); |
||
9021 | * // => true |
||
9022 | * |
||
9023 | * _.isNative(_); |
||
9024 | * // => false |
||
9025 | */ |
||
9026 | function isNative(value) { |
||
9027 | if (value == null) { |
||
9028 | return false; |
||
9029 | } |
||
9030 | if (isFunction(value)) { |
||
9031 | return reIsNative.test(fnToString.call(value)); |
||
9032 | } |
||
9033 | return isObjectLike(value) && (isHostObject(value) ? reIsNative : reIsHostCtor).test(value); |
||
9034 | } |
||
9035 | |||
9036 | /** |
||
9037 | * Checks if `value` is `null`. |
||
9038 | * |
||
9039 | * @static |
||
9040 | * @memberOf _ |
||
9041 | * @category Lang |
||
9042 | * @param {*} value The value to check. |
||
9043 | * @returns {boolean} Returns `true` if `value` is `null`, else `false`. |
||
9044 | * @example |
||
9045 | * |
||
9046 | * _.isNull(null); |
||
9047 | * // => true |
||
9048 | * |
||
9049 | * _.isNull(void 0); |
||
9050 | * // => false |
||
9051 | */ |
||
9052 | function isNull(value) { |
||
9053 | return value === null; |
||
9054 | } |
||
9055 | |||
9056 | /** |
||
9057 | * Checks if `value` is classified as a `Number` primitive or object. |
||
9058 | * |
||
9059 | * **Note:** To exclude `Infinity`, `-Infinity`, and `NaN`, which are classified |
||
9060 | * as numbers, use the `_.isFinite` method. |
||
9061 | * |
||
9062 | * @static |
||
9063 | * @memberOf _ |
||
9064 | * @category Lang |
||
9065 | * @param {*} value The value to check. |
||
9066 | * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. |
||
9067 | * @example |
||
9068 | * |
||
9069 | * _.isNumber(8.4); |
||
9070 | * // => true |
||
9071 | * |
||
9072 | * _.isNumber(NaN); |
||
9073 | * // => true |
||
9074 | * |
||
9075 | * _.isNumber('8.4'); |
||
9076 | * // => false |
||
9077 | */ |
||
9078 | function isNumber(value) { |
||
9079 | return typeof value == 'number' || (isObjectLike(value) && objToString.call(value) == numberTag); |
||
9080 | } |
||
9081 | |||
9082 | /** |
||
9083 | * Checks if `value` is a plain object, that is, an object created by the |
||
9084 | * `Object` constructor or one with a `[[Prototype]]` of `null`. |
||
9085 | * |
||
9086 | * **Note:** This method assumes objects created by the `Object` constructor |
||
9087 | * have no inherited enumerable properties. |
||
9088 | * |
||
9089 | * @static |
||
9090 | * @memberOf _ |
||
9091 | * @category Lang |
||
9092 | * @param {*} value The value to check. |
||
9093 | * @returns {boolean} Returns `true` if `value` is a plain object, else `false`. |
||
9094 | * @example |
||
9095 | * |
||
9096 | * function Foo() { |
||
9097 | * this.a = 1; |
||
9098 | * } |
||
9099 | * |
||
9100 | * _.isPlainObject(new Foo); |
||
9101 | * // => false |
||
9102 | * |
||
9103 | * _.isPlainObject([1, 2, 3]); |
||
9104 | * // => false |
||
9105 | * |
||
9106 | * _.isPlainObject({ 'x': 0, 'y': 0 }); |
||
9107 | * // => true |
||
9108 | * |
||
9109 | * _.isPlainObject(Object.create(null)); |
||
9110 | * // => true |
||
9111 | */ |
||
9112 | function isPlainObject(value) { |
||
9113 | var Ctor; |
||
9114 | |||
9115 | // Exit early for non `Object` objects. |
||
9116 | if (!(isObjectLike(value) && objToString.call(value) == objectTag && !isHostObject(value) && !isArguments(value)) || |
||
9117 | (!hasOwnProperty.call(value, 'constructor') && (Ctor = value.constructor, typeof Ctor == 'function' && !(Ctor instanceof Ctor)))) { |
||
9118 | return false; |
||
9119 | } |
||
9120 | // IE < 9 iterates inherited properties before own properties. If the first |
||
9121 | // iterated property is an object's own property then there are no inherited |
||
9122 | // enumerable properties. |
||
9123 | var result; |
||
9124 | if (lodash.support.ownLast) { |
||
9125 | baseForIn(value, function(subValue, key, object) { |
||
9126 | result = hasOwnProperty.call(object, key); |
||
9127 | return false; |
||
9128 | }); |
||
9129 | return result !== false; |
||
9130 | } |
||
9131 | // In most environments an object's own properties are iterated before |
||
9132 | // its inherited properties. If the last iterated property is an object's |
||
9133 | // own property then there are no inherited enumerable properties. |
||
9134 | baseForIn(value, function(subValue, key) { |
||
9135 | result = key; |
||
9136 | }); |
||
9137 | return result === undefined || hasOwnProperty.call(value, result); |
||
9138 | } |
||
9139 | |||
9140 | /** |
||
9141 | * Checks if `value` is classified as a `RegExp` object. |
||
9142 | * |
||
9143 | * @static |
||
9144 | * @memberOf _ |
||
9145 | * @category Lang |
||
9146 | * @param {*} value The value to check. |
||
9147 | * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. |
||
9148 | * @example |
||
9149 | * |
||
9150 | * _.isRegExp(/abc/); |
||
9151 | * // => true |
||
9152 | * |
||
9153 | * _.isRegExp('/abc/'); |
||
9154 | * // => false |
||
9155 | */ |
||
9156 | function isRegExp(value) { |
||
9157 | return isObject(value) && objToString.call(value) == regexpTag; |
||
9158 | } |
||
9159 | |||
9160 | /** |
||
9161 | * Checks if `value` is classified as a `String` primitive or object. |
||
9162 | * |
||
9163 | * @static |
||
9164 | * @memberOf _ |
||
9165 | * @category Lang |
||
9166 | * @param {*} value The value to check. |
||
9167 | * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. |
||
9168 | * @example |
||
9169 | * |
||
9170 | * _.isString('abc'); |
||
9171 | * // => true |
||
9172 | * |
||
9173 | * _.isString(1); |
||
9174 | * // => false |
||
9175 | */ |
||
9176 | function isString(value) { |
||
9177 | return typeof value == 'string' || (isObjectLike(value) && objToString.call(value) == stringTag); |
||
9178 | } |
||
9179 | |||
9180 | /** |
||
9181 | * Checks if `value` is classified as a typed array. |
||
9182 | * |
||
9183 | * @static |
||
9184 | * @memberOf _ |
||
9185 | * @category Lang |
||
9186 | * @param {*} value The value to check. |
||
9187 | * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. |
||
9188 | * @example |
||
9189 | * |
||
9190 | * _.isTypedArray(new Uint8Array); |
||
9191 | * // => true |
||
9192 | * |
||
9193 | * _.isTypedArray([]); |
||
9194 | * // => false |
||
9195 | */ |
||
9196 | function isTypedArray(value) { |
||
9197 | return isObjectLike(value) && isLength(value.length) && !!typedArrayTags[objToString.call(value)]; |
||
9198 | } |
||
9199 | |||
9200 | /** |
||
9201 | * Checks if `value` is `undefined`. |
||
9202 | * |
||
9203 | * @static |
||
9204 | * @memberOf _ |
||
9205 | * @category Lang |
||
9206 | * @param {*} value The value to check. |
||
9207 | * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`. |
||
9208 | * @example |
||
9209 | * |
||
9210 | * _.isUndefined(void 0); |
||
9211 | * // => true |
||
9212 | * |
||
9213 | * _.isUndefined(null); |
||
9214 | * // => false |
||
9215 | */ |
||
9216 | function isUndefined(value) { |
||
9217 | return value === undefined; |
||
9218 | } |
||
9219 | |||
9220 | /** |
||
9221 | * Checks if `value` is less than `other`. |
||
9222 | * |
||
9223 | * @static |
||
9224 | * @memberOf _ |
||
9225 | * @category Lang |
||
9226 | * @param {*} value The value to compare. |
||
9227 | * @param {*} other The other value to compare. |
||
9228 | * @returns {boolean} Returns `true` if `value` is less than `other`, else `false`. |
||
9229 | * @example |
||
9230 | * |
||
9231 | * _.lt(1, 3); |
||
9232 | * // => true |
||
9233 | * |
||
9234 | * _.lt(3, 3); |
||
9235 | * // => false |
||
9236 | * |
||
9237 | * _.lt(3, 1); |
||
9238 | * // => false |
||
9239 | */ |
||
9240 | function lt(value, other) { |
||
9241 | return value < other; |
||
9242 | } |
||
9243 | |||
9244 | /** |
||
9245 | * Checks if `value` is less than or equal to `other`. |
||
9246 | * |
||
9247 | * @static |
||
9248 | * @memberOf _ |
||
9249 | * @category Lang |
||
9250 | * @param {*} value The value to compare. |
||
9251 | * @param {*} other The other value to compare. |
||
9252 | * @returns {boolean} Returns `true` if `value` is less than or equal to `other`, else `false`. |
||
9253 | * @example |
||
9254 | * |
||
9255 | * _.lte(1, 3); |
||
9256 | * // => true |
||
9257 | * |
||
9258 | * _.lte(3, 3); |
||
9259 | * // => true |
||
9260 | * |
||
9261 | * _.lte(3, 1); |
||
9262 | * // => false |
||
9263 | */ |
||
9264 | function lte(value, other) { |
||
9265 | return value <= other; |
||
9266 | } |
||
9267 | |||
9268 | /** |
||
9269 | * Converts `value` to an array. |
||
9270 | * |
||
9271 | * @static |
||
9272 | * @memberOf _ |
||
9273 | * @category Lang |
||
9274 | * @param {*} value The value to convert. |
||
9275 | * @returns {Array} Returns the converted array. |
||
9276 | * @example |
||
9277 | * |
||
9278 | * (function() { |
||
9279 | * return _.toArray(arguments).slice(1); |
||
9280 | * }(1, 2, 3)); |
||
9281 | * // => [2, 3] |
||
9282 | */ |
||
9283 | function toArray(value) { |
||
9284 | var length = value ? getLength(value) : 0; |
||
9285 | if (!isLength(length)) { |
||
9286 | return values(value); |
||
9287 | } |
||
9288 | if (!length) { |
||
9289 | return []; |
||
9290 | } |
||
9291 | return (lodash.support.unindexedChars && isString(value)) |
||
9292 | ? value.split('') |
||
9293 | : arrayCopy(value); |
||
9294 | } |
||
9295 | |||
9296 | /** |
||
9297 | * Converts `value` to a plain object flattening inherited enumerable |
||
9298 | * properties of `value` to own properties of the plain object. |
||
9299 | * |
||
9300 | * @static |
||
9301 | * @memberOf _ |
||
9302 | * @category Lang |
||
9303 | * @param {*} value The value to convert. |
||
9304 | * @returns {Object} Returns the converted plain object. |
||
9305 | * @example |
||
9306 | * |
||
9307 | * function Foo() { |
||
9308 | * this.b = 2; |
||
9309 | * } |
||
9310 | * |
||
9311 | * Foo.prototype.c = 3; |
||
9312 | * |
||
9313 | * _.assign({ 'a': 1 }, new Foo); |
||
9314 | * // => { 'a': 1, 'b': 2 } |
||
9315 | * |
||
9316 | * _.assign({ 'a': 1 }, _.toPlainObject(new Foo)); |
||
9317 | * // => { 'a': 1, 'b': 2, 'c': 3 } |
||
9318 | */ |
||
9319 | function toPlainObject(value) { |
||
9320 | return baseCopy(value, keysIn(value)); |
||
9321 | } |
||
9322 | |||
9323 | /*------------------------------------------------------------------------*/ |
||
9324 | |||
9325 | /** |
||
9326 | * Recursively merges own enumerable properties of the source object(s), that |
||
9327 | * don't resolve to `undefined` into the destination object. Subsequent sources |
||
9328 | * overwrite property assignments of previous sources. If `customizer` is |
||
9329 | * provided it's invoked to produce the merged values of the destination and |
||
9330 | * source properties. If `customizer` returns `undefined` merging is handled |
||
9331 | * by the method instead. The `customizer` is bound to `thisArg` and invoked |
||
9332 | * with five arguments: (objectValue, sourceValue, key, object, source). |
||
9333 | * |
||
9334 | * @static |
||
9335 | * @memberOf _ |
||
9336 | * @category Object |
||
9337 | * @param {Object} object The destination object. |
||
9338 | * @param {...Object} [sources] The source objects. |
||
9339 | * @param {Function} [customizer] The function to customize assigned values. |
||
9340 | * @param {*} [thisArg] The `this` binding of `customizer`. |
||
9341 | * @returns {Object} Returns `object`. |
||
9342 | * @example |
||
9343 | * |
||
9344 | * var users = { |
||
9345 | * 'data': [{ 'user': 'barney' }, { 'user': 'fred' }] |
||
9346 | * }; |
||
9347 | * |
||
9348 | * var ages = { |
||
9349 | * 'data': [{ 'age': 36 }, { 'age': 40 }] |
||
9350 | * }; |
||
9351 | * |
||
9352 | * _.merge(users, ages); |
||
9353 | * // => { 'data': [{ 'user': 'barney', 'age': 36 }, { 'user': 'fred', 'age': 40 }] } |
||
9354 | * |
||
9355 | * // using a customizer callback |
||
9356 | * var object = { |
||
9357 | * 'fruits': ['apple'], |
||
9358 | * 'vegetables': ['beet'] |
||
9359 | * }; |
||
9360 | * |
||
9361 | * var other = { |
||
9362 | * 'fruits': ['banana'], |
||
9363 | * 'vegetables': ['carrot'] |
||
9364 | * }; |
||
9365 | * |
||
9366 | * _.merge(object, other, function(a, b) { |
||
9367 | * if (_.isArray(a)) { |
||
9368 | * return a.concat(b); |
||
9369 | * } |
||
9370 | * }); |
||
9371 | * // => { 'fruits': ['apple', 'banana'], 'vegetables': ['beet', 'carrot'] } |
||
9372 | */ |
||
9373 | var merge = createAssigner(baseMerge); |
||
9374 | |||
9375 | /** |
||
9376 | * Assigns own enumerable properties of source object(s) to the destination |
||
9377 | * object. Subsequent sources overwrite property assignments of previous sources. |
||
9378 | * If `customizer` is provided it's invoked to produce the assigned values. |
||
9379 | * The `customizer` is bound to `thisArg` and invoked with five arguments: |
||
9380 | * (objectValue, sourceValue, key, object, source). |
||
9381 | * |
||
9382 | * **Note:** This method mutates `object` and is based on |
||
9383 | * [`Object.assign`](http://ecma-international.org/ecma-262/6.0/#sec-object.assign). |
||
9384 | * |
||
9385 | * @static |
||
9386 | * @memberOf _ |
||
9387 | * @alias extend |
||
9388 | * @category Object |
||
9389 | * @param {Object} object The destination object. |
||
9390 | * @param {...Object} [sources] The source objects. |
||
9391 | * @param {Function} [customizer] The function to customize assigned values. |
||
9392 | * @param {*} [thisArg] The `this` binding of `customizer`. |
||
9393 | * @returns {Object} Returns `object`. |
||
9394 | * @example |
||
9395 | * |
||
9396 | * _.assign({ 'user': 'barney' }, { 'age': 40 }, { 'user': 'fred' }); |
||
9397 | * // => { 'user': 'fred', 'age': 40 } |
||
9398 | * |
||
9399 | * // using a customizer callback |
||
9400 | * var defaults = _.partialRight(_.assign, function(value, other) { |
||
9401 | * return _.isUndefined(value) ? other : value; |
||
9402 | * }); |
||
9403 | * |
||
9404 | * defaults({ 'user': 'barney' }, { 'age': 36 }, { 'user': 'fred' }); |
||
9405 | * // => { 'user': 'barney', 'age': 36 } |
||
9406 | */ |
||
9407 | var assign = createAssigner(function(object, source, customizer) { |
||
9408 | return customizer |
||
9409 | ? assignWith(object, source, customizer) |
||
9410 | : baseAssign(object, source); |
||
9411 | }); |
||
9412 | |||
9413 | /** |
||
9414 | * Creates an object that inherits from the given `prototype` object. If a |
||
9415 | * `properties` object is provided its own enumerable properties are assigned |
||
9416 | * to the created object. |
||
9417 | * |
||
9418 | * @static |
||
9419 | * @memberOf _ |
||
9420 | * @category Object |
||
9421 | * @param {Object} prototype The object to inherit from. |
||
9422 | * @param {Object} [properties] The properties to assign to the object. |
||
9423 | * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. |
||
9424 | * @returns {Object} Returns the new object. |
||
9425 | * @example |
||
9426 | * |
||
9427 | * function Shape() { |
||
9428 | * this.x = 0; |
||
9429 | * this.y = 0; |
||
9430 | * } |
||
9431 | * |
||
9432 | * function Circle() { |
||
9433 | * Shape.call(this); |
||
9434 | * } |
||
9435 | * |
||
9436 | * Circle.prototype = _.create(Shape.prototype, { |
||
9437 | * 'constructor': Circle |
||
9438 | * }); |
||
9439 | * |
||
9440 | * var circle = new Circle; |
||
9441 | * circle instanceof Circle; |
||
9442 | * // => true |
||
9443 | * |
||
9444 | * circle instanceof Shape; |
||
9445 | * // => true |
||
9446 | */ |
||
9447 | function create(prototype, properties, guard) { |
||
9448 | var result = baseCreate(prototype); |
||
9449 | if (guard && isIterateeCall(prototype, properties, guard)) { |
||
9450 | properties = undefined; |
||
9451 | } |
||
9452 | return properties ? baseAssign(result, properties) : result; |
||
9453 | } |
||
9454 | |||
9455 | /** |
||
9456 | * Assigns own enumerable properties of source object(s) to the destination |
||
9457 | * object for all destination properties that resolve to `undefined`. Once a |
||
9458 | * property is set, additional values of the same property are ignored. |
||
9459 | * |
||
9460 | * **Note:** This method mutates `object`. |
||
9461 | * |
||
9462 | * @static |
||
9463 | * @memberOf _ |
||
9464 | * @category Object |
||
9465 | * @param {Object} object The destination object. |
||
9466 | * @param {...Object} [sources] The source objects. |
||
9467 | * @returns {Object} Returns `object`. |
||
9468 | * @example |
||
9469 | * |
||
9470 | * _.defaults({ 'user': 'barney' }, { 'age': 36 }, { 'user': 'fred' }); |
||
9471 | * // => { 'user': 'barney', 'age': 36 } |
||
9472 | */ |
||
9473 | var defaults = createDefaults(assign, assignDefaults); |
||
9474 | |||
9475 | /** |
||
9476 | * This method is like `_.defaults` except that it recursively assigns |
||
9477 | * default properties. |
||
9478 | * |
||
9479 | * **Note:** This method mutates `object`. |
||
9480 | * |
||
9481 | * @static |
||
9482 | * @memberOf _ |
||
9483 | * @category Object |
||
9484 | * @param {Object} object The destination object. |
||
9485 | * @param {...Object} [sources] The source objects. |
||
9486 | * @returns {Object} Returns `object`. |
||
9487 | * @example |
||
9488 | * |
||
9489 | * _.defaultsDeep({ 'user': { 'name': 'barney' } }, { 'user': { 'name': 'fred', 'age': 36 } }); |
||
9490 | * // => { 'user': { 'name': 'barney', 'age': 36 } } |
||
9491 | * |
||
9492 | */ |
||
9493 | var defaultsDeep = createDefaults(merge, mergeDefaults); |
||
9494 | |||
9495 | /** |
||
9496 | * This method is like `_.find` except that it returns the key of the first |
||
9497 | * element `predicate` returns truthy for instead of the element itself. |
||
9498 | * |
||
9499 | * If a property name is provided for `predicate` the created `_.property` |
||
9500 | * style callback returns the property value of the given element. |
||
9501 | * |
||
9502 | * If a value is also provided for `thisArg` the created `_.matchesProperty` |
||
9503 | * style callback returns `true` for elements that have a matching property |
||
9504 | * value, else `false`. |
||
9505 | * |
||
9506 | * If an object is provided for `predicate` the created `_.matches` style |
||
9507 | * callback returns `true` for elements that have the properties of the given |
||
9508 | * object, else `false`. |
||
9509 | * |
||
9510 | * @static |
||
9511 | * @memberOf _ |
||
9512 | * @category Object |
||
9513 | * @param {Object} object The object to search. |
||
9514 | * @param {Function|Object|string} [predicate=_.identity] The function invoked |
||
9515 | * per iteration. |
||
9516 | * @param {*} [thisArg] The `this` binding of `predicate`. |
||
9517 | * @returns {string|undefined} Returns the key of the matched element, else `undefined`. |
||
9518 | * @example |
||
9519 | * |
||
9520 | * var users = { |
||
9521 | * 'barney': { 'age': 36, 'active': true }, |
||
9522 | * 'fred': { 'age': 40, 'active': false }, |
||
9523 | * 'pebbles': { 'age': 1, 'active': true } |
||
9524 | * }; |
||
9525 | * |
||
9526 | * _.findKey(users, function(chr) { |
||
9527 | * return chr.age < 40; |
||
9528 | * }); |
||
9529 | * // => 'barney' (iteration order is not guaranteed) |
||
9530 | * |
||
9531 | * // using the `_.matches` callback shorthand |
||
9532 | * _.findKey(users, { 'age': 1, 'active': true }); |
||
9533 | * // => 'pebbles' |
||
9534 | * |
||
9535 | * // using the `_.matchesProperty` callback shorthand |
||
9536 | * _.findKey(users, 'active', false); |
||
9537 | * // => 'fred' |
||
9538 | * |
||
9539 | * // using the `_.property` callback shorthand |
||
9540 | * _.findKey(users, 'active'); |
||
9541 | * // => 'barney' |
||
9542 | */ |
||
9543 | var findKey = createFindKey(baseForOwn); |
||
9544 | |||
9545 | /** |
||
9546 | * This method is like `_.findKey` except that it iterates over elements of |
||
9547 | * a collection in the opposite order. |
||
9548 | * |
||
9549 | * If a property name is provided for `predicate` the created `_.property` |
||
9550 | * style callback returns the property value of the given element. |
||
9551 | * |
||
9552 | * If a value is also provided for `thisArg` the created `_.matchesProperty` |
||
9553 | * style callback returns `true` for elements that have a matching property |
||
9554 | * value, else `false`. |
||
9555 | * |
||
9556 | * If an object is provided for `predicate` the created `_.matches` style |
||
9557 | * callback returns `true` for elements that have the properties of the given |
||
9558 | * object, else `false`. |
||
9559 | * |
||
9560 | * @static |
||
9561 | * @memberOf _ |
||
9562 | * @category Object |
||
9563 | * @param {Object} object The object to search. |
||
9564 | * @param {Function|Object|string} [predicate=_.identity] The function invoked |
||
9565 | * per iteration. |
||
9566 | * @param {*} [thisArg] The `this` binding of `predicate`. |
||
9567 | * @returns {string|undefined} Returns the key of the matched element, else `undefined`. |
||
9568 | * @example |
||
9569 | * |
||
9570 | * var users = { |
||
9571 | * 'barney': { 'age': 36, 'active': true }, |
||
9572 | * 'fred': { 'age': 40, 'active': false }, |
||
9573 | * 'pebbles': { 'age': 1, 'active': true } |
||
9574 | * }; |
||
9575 | * |
||
9576 | * _.findLastKey(users, function(chr) { |
||
9577 | * return chr.age < 40; |
||
9578 | * }); |
||
9579 | * // => returns `pebbles` assuming `_.findKey` returns `barney` |
||
9580 | * |
||
9581 | * // using the `_.matches` callback shorthand |
||
9582 | * _.findLastKey(users, { 'age': 36, 'active': true }); |
||
9583 | * // => 'barney' |
||
9584 | * |
||
9585 | * // using the `_.matchesProperty` callback shorthand |
||
9586 | * _.findLastKey(users, 'active', false); |
||
9587 | * // => 'fred' |
||
9588 | * |
||
9589 | * // using the `_.property` callback shorthand |
||
9590 | * _.findLastKey(users, 'active'); |
||
9591 | * // => 'pebbles' |
||
9592 | */ |
||
9593 | var findLastKey = createFindKey(baseForOwnRight); |
||
9594 | |||
9595 | /** |
||
9596 | * Iterates over own and inherited enumerable properties of an object invoking |
||
9597 | * `iteratee` for each property. The `iteratee` is bound to `thisArg` and invoked |
||
9598 | * with three arguments: (value, key, object). Iteratee functions may exit |
||
9599 | * iteration early by explicitly returning `false`. |
||
9600 | * |
||
9601 | * @static |
||
9602 | * @memberOf _ |
||
9603 | * @category Object |
||
9604 | * @param {Object} object The object to iterate over. |
||
9605 | * @param {Function} [iteratee=_.identity] The function invoked per iteration. |
||
9606 | * @param {*} [thisArg] The `this` binding of `iteratee`. |
||
9607 | * @returns {Object} Returns `object`. |
||
9608 | * @example |
||
9609 | * |
||
9610 | * function Foo() { |
||
9611 | * this.a = 1; |
||
9612 | * this.b = 2; |
||
9613 | * } |
||
9614 | * |
||
9615 | * Foo.prototype.c = 3; |
||
9616 | * |
||
9617 | * _.forIn(new Foo, function(value, key) { |
||
9618 | * console.log(key); |
||
9619 | * }); |
||
9620 | * // => logs 'a', 'b', and 'c' (iteration order is not guaranteed) |
||
9621 | */ |
||
9622 | var forIn = createForIn(baseFor); |
||
9623 | |||
9624 | /** |
||
9625 | * This method is like `_.forIn` except that it iterates over properties of |
||
9626 | * `object` in the opposite order. |
||
9627 | * |
||
9628 | * @static |
||
9629 | * @memberOf _ |
||
9630 | * @category Object |
||
9631 | * @param {Object} object The object to iterate over. |
||
9632 | * @param {Function} [iteratee=_.identity] The function invoked per iteration. |
||
9633 | * @param {*} [thisArg] The `this` binding of `iteratee`. |
||
9634 | * @returns {Object} Returns `object`. |
||
9635 | * @example |
||
9636 | * |
||
9637 | * function Foo() { |
||
9638 | * this.a = 1; |
||
9639 | * this.b = 2; |
||
9640 | * } |
||
9641 | * |
||
9642 | * Foo.prototype.c = 3; |
||
9643 | * |
||
9644 | * _.forInRight(new Foo, function(value, key) { |
||
9645 | * console.log(key); |
||
9646 | * }); |
||
9647 | * // => logs 'c', 'b', and 'a' assuming `_.forIn ` logs 'a', 'b', and 'c' |
||
9648 | */ |
||
9649 | var forInRight = createForIn(baseForRight); |
||
9650 | |||
9651 | /** |
||
9652 | * Iterates over own enumerable properties of an object invoking `iteratee` |
||
9653 | * for each property. The `iteratee` is bound to `thisArg` and invoked with |
||
9654 | * three arguments: (value, key, object). Iteratee functions may exit iteration |
||
9655 | * early by explicitly returning `false`. |
||
9656 | * |
||
9657 | * @static |
||
9658 | * @memberOf _ |
||
9659 | * @category Object |
||
9660 | * @param {Object} object The object to iterate over. |
||
9661 | * @param {Function} [iteratee=_.identity] The function invoked per iteration. |
||
9662 | * @param {*} [thisArg] The `this` binding of `iteratee`. |
||
9663 | * @returns {Object} Returns `object`. |
||
9664 | * @example |
||
9665 | * |
||
9666 | * function Foo() { |
||
9667 | * this.a = 1; |
||
9668 | * this.b = 2; |
||
9669 | * } |
||
9670 | * |
||
9671 | * Foo.prototype.c = 3; |
||
9672 | * |
||
9673 | * _.forOwn(new Foo, function(value, key) { |
||
9674 | * console.log(key); |
||
9675 | * }); |
||
9676 | * // => logs 'a' and 'b' (iteration order is not guaranteed) |
||
9677 | */ |
||
9678 | var forOwn = createForOwn(baseForOwn); |
||
9679 | |||
9680 | /** |
||
9681 | * This method is like `_.forOwn` except that it iterates over properties of |
||
9682 | * `object` in the opposite order. |
||
9683 | * |
||
9684 | * @static |
||
9685 | * @memberOf _ |
||
9686 | * @category Object |
||
9687 | * @param {Object} object The object to iterate over. |
||
9688 | * @param {Function} [iteratee=_.identity] The function invoked per iteration. |
||
9689 | * @param {*} [thisArg] The `this` binding of `iteratee`. |
||
9690 | * @returns {Object} Returns `object`. |
||
9691 | * @example |
||
9692 | * |
||
9693 | * function Foo() { |
||
9694 | * this.a = 1; |
||
9695 | * this.b = 2; |
||
9696 | * } |
||
9697 | * |
||
9698 | * Foo.prototype.c = 3; |
||
9699 | * |
||
9700 | * _.forOwnRight(new Foo, function(value, key) { |
||
9701 | * console.log(key); |
||
9702 | * }); |
||
9703 | * // => logs 'b' and 'a' assuming `_.forOwn` logs 'a' and 'b' |
||
9704 | */ |
||
9705 | var forOwnRight = createForOwn(baseForOwnRight); |
||
9706 | |||
9707 | /** |
||
9708 | * Creates an array of function property names from all enumerable properties, |
||
9709 | * own and inherited, of `object`. |
||
9710 | * |
||
9711 | * @static |
||
9712 | * @memberOf _ |
||
9713 | * @alias methods |
||
9714 | * @category Object |
||
9715 | * @param {Object} object The object to inspect. |
||
9716 | * @returns {Array} Returns the new array of property names. |
||
9717 | * @example |
||
9718 | * |
||
9719 | * _.functions(_); |
||
9720 | * // => ['after', 'ary', 'assign', ...] |
||
9721 | */ |
||
9722 | function functions(object) { |
||
9723 | return baseFunctions(object, keysIn(object)); |
||
9724 | } |
||
9725 | |||
9726 | /** |
||
9727 | * Gets the property value at `path` of `object`. If the resolved value is |
||
9728 | * `undefined` the `defaultValue` is used in its place. |
||
9729 | * |
||
9730 | * @static |
||
9731 | * @memberOf _ |
||
9732 | * @category Object |
||
9733 | * @param {Object} object The object to query. |
||
9734 | * @param {Array|string} path The path of the property to get. |
||
9735 | * @param {*} [defaultValue] The value returned if the resolved value is `undefined`. |
||
9736 | * @returns {*} Returns the resolved value. |
||
9737 | * @example |
||
9738 | * |
||
9739 | * var object = { 'a': [{ 'b': { 'c': 3 } }] }; |
||
9740 | * |
||
9741 | * _.get(object, 'a[0].b.c'); |
||
9742 | * // => 3 |
||
9743 | * |
||
9744 | * _.get(object, ['a', '0', 'b', 'c']); |
||
9745 | * // => 3 |
||
9746 | * |
||
9747 | * _.get(object, 'a.b.c', 'default'); |
||
9748 | * // => 'default' |
||
9749 | */ |
||
9750 | function get(object, path, defaultValue) { |
||
9751 | var result = object == null ? undefined : baseGet(object, toPath(path), (path + '')); |
||
9752 | return result === undefined ? defaultValue : result; |
||
9753 | } |
||
9754 | |||
9755 | /** |
||
9756 | * Checks if `path` is a direct property. |
||
9757 | * |
||
9758 | * @static |
||
9759 | * @memberOf _ |
||
9760 | * @category Object |
||
9761 | * @param {Object} object The object to query. |
||
9762 | * @param {Array|string} path The path to check. |
||
9763 | * @returns {boolean} Returns `true` if `path` is a direct property, else `false`. |
||
9764 | * @example |
||
9765 | * |
||
9766 | * var object = { 'a': { 'b': { 'c': 3 } } }; |
||
9767 | * |
||
9768 | * _.has(object, 'a'); |
||
9769 | * // => true |
||
9770 | * |
||
9771 | * _.has(object, 'a.b.c'); |
||
9772 | * // => true |
||
9773 | * |
||
9774 | * _.has(object, ['a', 'b', 'c']); |
||
9775 | * // => true |
||
9776 | */ |
||
9777 | function has(object, path) { |
||
9778 | if (object == null) { |
||
9779 | return false; |
||
9780 | } |
||
9781 | var result = hasOwnProperty.call(object, path); |
||
9782 | if (!result && !isKey(path)) { |
||
9783 | path = toPath(path); |
||
9784 | object = path.length == 1 ? object : baseGet(object, baseSlice(path, 0, -1)); |
||
9785 | if (object == null) { |
||
9786 | return false; |
||
9787 | } |
||
9788 | path = last(path); |
||
9789 | result = hasOwnProperty.call(object, path); |
||
9790 | } |
||
9791 | return result || (isLength(object.length) && isIndex(path, object.length) && |
||
9792 | (isArray(object) || isArguments(object) || isString(object))); |
||
9793 | } |
||
9794 | |||
9795 | /** |
||
9796 | * Creates an object composed of the inverted keys and values of `object`. |
||
9797 | * If `object` contains duplicate values, subsequent values overwrite property |
||
9798 | * assignments of previous values unless `multiValue` is `true`. |
||
9799 | * |
||
9800 | * @static |
||
9801 | * @memberOf _ |
||
9802 | * @category Object |
||
9803 | * @param {Object} object The object to invert. |
||
9804 | * @param {boolean} [multiValue] Allow multiple values per key. |
||
9805 | * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. |
||
9806 | * @returns {Object} Returns the new inverted object. |
||
9807 | * @example |
||
9808 | * |
||
9809 | * var object = { 'a': 1, 'b': 2, 'c': 1 }; |
||
9810 | * |
||
9811 | * _.invert(object); |
||
9812 | * // => { '1': 'c', '2': 'b' } |
||
9813 | * |
||
9814 | * // with `multiValue` |
||
9815 | * _.invert(object, true); |
||
9816 | * // => { '1': ['a', 'c'], '2': ['b'] } |
||
9817 | */ |
||
9818 | function invert(object, multiValue, guard) { |
||
9819 | if (guard && isIterateeCall(object, multiValue, guard)) { |
||
9820 | multiValue = undefined; |
||
9821 | } |
||
9822 | var index = -1, |
||
9823 | props = keys(object), |
||
9824 | length = props.length, |
||
9825 | result = {}; |
||
9826 | |||
9827 | while (++index < length) { |
||
9828 | var key = props[index], |
||
9829 | value = object[key]; |
||
9830 | |||
9831 | if (multiValue) { |
||
9832 | if (hasOwnProperty.call(result, value)) { |
||
9833 | result[value].push(key); |
||
9834 | } else { |
||
9835 | result[value] = [key]; |
||
9836 | } |
||
9837 | } |
||
9838 | else { |
||
9839 | result[value] = key; |
||
9840 | } |
||
9841 | } |
||
9842 | return result; |
||
9843 | } |
||
9844 | |||
9845 | /** |
||
9846 | * Creates an array of the own enumerable property names of `object`. |
||
9847 | * |
||
9848 | * **Note:** Non-object values are coerced to objects. See the |
||
9849 | * [ES spec](http://ecma-international.org/ecma-262/6.0/#sec-object.keys) |
||
9850 | * for more details. |
||
9851 | * |
||
9852 | * @static |
||
9853 | * @memberOf _ |
||
9854 | * @category Object |
||
9855 | * @param {Object} object The object to query. |
||
9856 | * @returns {Array} Returns the array of property names. |
||
9857 | * @example |
||
9858 | * |
||
9859 | * function Foo() { |
||
9860 | * this.a = 1; |
||
9861 | * this.b = 2; |
||
9862 | * } |
||
9863 | * |
||
9864 | * Foo.prototype.c = 3; |
||
9865 | * |
||
9866 | * _.keys(new Foo); |
||
9867 | * // => ['a', 'b'] (iteration order is not guaranteed) |
||
9868 | * |
||
9869 | * _.keys('hi'); |
||
9870 | * // => ['0', '1'] |
||
9871 | */ |
||
9872 | var keys = !nativeKeys ? shimKeys : function(object) { |
||
9873 | var Ctor = object == null ? undefined : object.constructor; |
||
9874 | if ((typeof Ctor == 'function' && Ctor.prototype === object) || |
||
9875 | (typeof object == 'function' ? lodash.support.enumPrototypes : isArrayLike(object))) { |
||
9876 | return shimKeys(object); |
||
9877 | } |
||
9878 | return isObject(object) ? nativeKeys(object) : []; |
||
9879 | }; |
||
9880 | |||
9881 | /** |
||
9882 | * Creates an array of the own and inherited enumerable property names of `object`. |
||
9883 | * |
||
9884 | * **Note:** Non-object values are coerced to objects. |
||
9885 | * |
||
9886 | * @static |
||
9887 | * @memberOf _ |
||
9888 | * @category Object |
||
9889 | * @param {Object} object The object to query. |
||
9890 | * @returns {Array} Returns the array of property names. |
||
9891 | * @example |
||
9892 | * |
||
9893 | * function Foo() { |
||
9894 | * this.a = 1; |
||
9895 | * this.b = 2; |
||
9896 | * } |
||
9897 | * |
||
9898 | * Foo.prototype.c = 3; |
||
9899 | * |
||
9900 | * _.keysIn(new Foo); |
||
9901 | * // => ['a', 'b', 'c'] (iteration order is not guaranteed) |
||
9902 | */ |
||
9903 | function keysIn(object) { |
||
9904 | if (object == null) { |
||
9905 | return []; |
||
9906 | } |
||
9907 | if (!isObject(object)) { |
||
9908 | object = Object(object); |
||
9909 | } |
||
9910 | var length = object.length, |
||
9911 | support = lodash.support; |
||
9912 | |||
9913 | length = (length && isLength(length) && |
||
9914 | (isArray(object) || isArguments(object) || isString(object)) && length) || 0; |
||
9915 | |||
9916 | var Ctor = object.constructor, |
||
9917 | index = -1, |
||
9918 | proto = (isFunction(Ctor) && Ctor.prototype) || objectProto, |
||
9919 | isProto = proto === object, |
||
9920 | result = Array(length), |
||
9921 | skipIndexes = length > 0, |
||
9922 | skipErrorProps = support.enumErrorProps && (object === errorProto || object instanceof Error), |
||
9923 | skipProto = support.enumPrototypes && isFunction(object); |
||
9924 | |||
9925 | while (++index < length) { |
||
9926 | result[index] = (index + ''); |
||
9927 | } |
||
9928 | // lodash skips the `constructor` property when it infers it's iterating |
||
9929 | // over a `prototype` object because IE < 9 can't set the `[[Enumerable]]` |
||
9930 | // attribute of an existing property and the `constructor` property of a |
||
9931 | // prototype defaults to non-enumerable. |
||
9932 | for (var key in object) { |
||
9933 | if (!(skipProto && key == 'prototype') && |
||
9934 | !(skipErrorProps && (key == 'message' || key == 'name')) && |
||
9935 | !(skipIndexes && isIndex(key, length)) && |
||
9936 | !(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) { |
||
9937 | result.push(key); |
||
9938 | } |
||
9939 | } |
||
9940 | if (support.nonEnumShadows && object !== objectProto) { |
||
9941 | var tag = object === stringProto ? stringTag : (object === errorProto ? errorTag : objToString.call(object)), |
||
9942 | nonEnums = nonEnumProps[tag] || nonEnumProps[objectTag]; |
||
9943 | |||
9944 | if (tag == objectTag) { |
||
9945 | proto = objectProto; |
||
9946 | } |
||
9947 | length = shadowProps.length; |
||
9948 | while (length--) { |
||
9949 | key = shadowProps[length]; |
||
9950 | var nonEnum = nonEnums[key]; |
||
9951 | if (!(isProto && nonEnum) && |
||
9952 | (nonEnum ? hasOwnProperty.call(object, key) : object[key] !== proto[key])) { |
||
9953 | result.push(key); |
||
9954 | } |
||
9955 | } |
||
9956 | } |
||
9957 | return result; |
||
9958 | } |
||
9959 | |||
9960 | /** |
||
9961 | * The opposite of `_.mapValues`; this method creates an object with the |
||
9962 | * same values as `object` and keys generated by running each own enumerable |
||
9963 | * property of `object` through `iteratee`. |
||
9964 | * |
||
9965 | * @static |
||
9966 | * @memberOf _ |
||
9967 | * @category Object |
||
9968 | * @param {Object} object The object to iterate over. |
||
9969 | * @param {Function|Object|string} [iteratee=_.identity] The function invoked |
||
9970 | * per iteration. |
||
9971 | * @param {*} [thisArg] The `this` binding of `iteratee`. |
||
9972 | * @returns {Object} Returns the new mapped object. |
||
9973 | * @example |
||
9974 | * |
||
9975 | * _.mapKeys({ 'a': 1, 'b': 2 }, function(value, key) { |
||
9976 | * return key + value; |
||
9977 | * }); |
||
9978 | * // => { 'a1': 1, 'b2': 2 } |
||
9979 | */ |
||
9980 | var mapKeys = createObjectMapper(true); |
||
9981 | |||
9982 | /** |
||
9983 | * Creates an object with the same keys as `object` and values generated by |
||
9984 | * running each own enumerable property of `object` through `iteratee`. The |
||
9985 | * iteratee function is bound to `thisArg` and invoked with three arguments: |
||
9986 | * (value, key, object). |
||
9987 | * |
||
9988 | * If a property name is provided for `iteratee` the created `_.property` |
||
9989 | * style callback returns the property value of the given element. |
||
9990 | * |
||
9991 | * If a value is also provided for `thisArg` the created `_.matchesProperty` |
||
9992 | * style callback returns `true` for elements that have a matching property |
||
9993 | * value, else `false`. |
||
9994 | * |
||
9995 | * If an object is provided for `iteratee` the created `_.matches` style |
||
9996 | * callback returns `true` for elements that have the properties of the given |
||
9997 | * object, else `false`. |
||
9998 | * |
||
9999 | * @static |
||
10000 | * @memberOf _ |
||
10001 | * @category Object |
||
10002 | * @param {Object} object The object to iterate over. |
||
10003 | * @param {Function|Object|string} [iteratee=_.identity] The function invoked |
||
10004 | * per iteration. |
||
10005 | * @param {*} [thisArg] The `this` binding of `iteratee`. |
||
10006 | * @returns {Object} Returns the new mapped object. |
||
10007 | * @example |
||
10008 | * |
||
10009 | * _.mapValues({ 'a': 1, 'b': 2 }, function(n) { |
||
10010 | * return n * 3; |
||
10011 | * }); |
||
10012 | * // => { 'a': 3, 'b': 6 } |
||
10013 | * |
||
10014 | * var users = { |
||
10015 | * 'fred': { 'user': 'fred', 'age': 40 }, |
||
10016 | * 'pebbles': { 'user': 'pebbles', 'age': 1 } |
||
10017 | * }; |
||
10018 | * |
||
10019 | * // using the `_.property` callback shorthand |
||
10020 | * _.mapValues(users, 'age'); |
||
10021 | * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed) |
||
10022 | */ |
||
10023 | var mapValues = createObjectMapper(); |
||
10024 | |||
10025 | /** |
||
10026 | * The opposite of `_.pick`; this method creates an object composed of the |
||
10027 | * own and inherited enumerable properties of `object` that are not omitted. |
||
10028 | * |
||
10029 | * @static |
||
10030 | * @memberOf _ |
||
10031 | * @category Object |
||
10032 | * @param {Object} object The source object. |
||
10033 | * @param {Function|...(string|string[])} [predicate] The function invoked per |
||
10034 | * iteration or property names to omit, specified as individual property |
||
10035 | * names or arrays of property names. |
||
10036 | * @param {*} [thisArg] The `this` binding of `predicate`. |
||
10037 | * @returns {Object} Returns the new object. |
||
10038 | * @example |
||
10039 | * |
||
10040 | * var object = { 'user': 'fred', 'age': 40 }; |
||
10041 | * |
||
10042 | * _.omit(object, 'age'); |
||
10043 | * // => { 'user': 'fred' } |
||
10044 | * |
||
10045 | * _.omit(object, _.isNumber); |
||
10046 | * // => { 'user': 'fred' } |
||
10047 | */ |
||
10048 | var omit = restParam(function(object, props) { |
||
10049 | if (object == null) { |
||
10050 | return {}; |
||
10051 | } |
||
10052 | if (typeof props[0] != 'function') { |
||
10053 | var props = arrayMap(baseFlatten(props), String); |
||
10054 | return pickByArray(object, baseDifference(keysIn(object), props)); |
||
10055 | } |
||
10056 | var predicate = bindCallback(props[0], props[1], 3); |
||
10057 | return pickByCallback(object, function(value, key, object) { |
||
10058 | return !predicate(value, key, object); |
||
10059 | }); |
||
10060 | }); |
||
10061 | |||
10062 | /** |
||
10063 | * Creates a two dimensional array of the key-value pairs for `object`, |
||
10064 | * e.g. `[[key1, value1], [key2, value2]]`. |
||
10065 | * |
||
10066 | * @static |
||
10067 | * @memberOf _ |
||
10068 | * @category Object |
||
10069 | * @param {Object} object The object to query. |
||
10070 | * @returns {Array} Returns the new array of key-value pairs. |
||
10071 | * @example |
||
10072 | * |
||
10073 | * _.pairs({ 'barney': 36, 'fred': 40 }); |
||
10074 | * // => [['barney', 36], ['fred', 40]] (iteration order is not guaranteed) |
||
10075 | */ |
||
10076 | function pairs(object) { |
||
10077 | object = toObject(object); |
||
10078 | |||
10079 | var index = -1, |
||
10080 | props = keys(object), |
||
10081 | length = props.length, |
||
10082 | result = Array(length); |
||
10083 | |||
10084 | while (++index < length) { |
||
10085 | var key = props[index]; |
||
10086 | result[index] = [key, object[key]]; |
||
10087 | } |
||
10088 | return result; |
||
10089 | } |
||
10090 | |||
10091 | /** |
||
10092 | * Creates an object composed of the picked `object` properties. Property |
||
10093 | * names may be specified as individual arguments or as arrays of property |
||
10094 | * names. If `predicate` is provided it's invoked for each property of `object` |
||
10095 | * picking the properties `predicate` returns truthy for. The predicate is |
||
10096 | * bound to `thisArg` and invoked with three arguments: (value, key, object). |
||
10097 | * |
||
10098 | * @static |
||
10099 | * @memberOf _ |
||
10100 | * @category Object |
||
10101 | * @param {Object} object The source object. |
||
10102 | * @param {Function|...(string|string[])} [predicate] The function invoked per |
||
10103 | * iteration or property names to pick, specified as individual property |
||
10104 | * names or arrays of property names. |
||
10105 | * @param {*} [thisArg] The `this` binding of `predicate`. |
||
10106 | * @returns {Object} Returns the new object. |
||
10107 | * @example |
||
10108 | * |
||
10109 | * var object = { 'user': 'fred', 'age': 40 }; |
||
10110 | * |
||
10111 | * _.pick(object, 'user'); |
||
10112 | * // => { 'user': 'fred' } |
||
10113 | * |
||
10114 | * _.pick(object, _.isString); |
||
10115 | * // => { 'user': 'fred' } |
||
10116 | */ |
||
10117 | var pick = restParam(function(object, props) { |
||
10118 | if (object == null) { |
||
10119 | return {}; |
||
10120 | } |
||
10121 | return typeof props[0] == 'function' |
||
10122 | ? pickByCallback(object, bindCallback(props[0], props[1], 3)) |
||
10123 | : pickByArray(object, baseFlatten(props)); |
||
10124 | }); |
||
10125 | |||
10126 | /** |
||
10127 | * This method is like `_.get` except that if the resolved value is a function |
||
10128 | * it's invoked with the `this` binding of its parent object and its result |
||
10129 | * is returned. |
||
10130 | * |
||
10131 | * @static |
||
10132 | * @memberOf _ |
||
10133 | * @category Object |
||
10134 | * @param {Object} object The object to query. |
||
10135 | * @param {Array|string} path The path of the property to resolve. |
||
10136 | * @param {*} [defaultValue] The value returned if the resolved value is `undefined`. |
||
10137 | * @returns {*} Returns the resolved value. |
||
10138 | * @example |
||
10139 | * |
||
10140 | * var object = { 'a': [{ 'b': { 'c1': 3, 'c2': _.constant(4) } }] }; |
||
10141 | * |
||
10142 | * _.result(object, 'a[0].b.c1'); |
||
10143 | * // => 3 |
||
10144 | * |
||
10145 | * _.result(object, 'a[0].b.c2'); |
||
10146 | * // => 4 |
||
10147 | * |
||
10148 | * _.result(object, 'a.b.c', 'default'); |
||
10149 | * // => 'default' |
||
10150 | * |
||
10151 | * _.result(object, 'a.b.c', _.constant('default')); |
||
10152 | * // => 'default' |
||
10153 | */ |
||
10154 | function result(object, path, defaultValue) { |
||
10155 | var result = object == null ? undefined : toObject(object)[path]; |
||
10156 | if (result === undefined) { |
||
10157 | if (object != null && !isKey(path, object)) { |
||
10158 | path = toPath(path); |
||
10159 | object = path.length == 1 ? object : baseGet(object, baseSlice(path, 0, -1)); |
||
10160 | result = object == null ? undefined : toObject(object)[last(path)]; |
||
10161 | } |
||
10162 | result = result === undefined ? defaultValue : result; |
||
10163 | } |
||
10164 | return isFunction(result) ? result.call(object) : result; |
||
10165 | } |
||
10166 | |||
10167 | /** |
||
10168 | * Sets the property value of `path` on `object`. If a portion of `path` |
||
10169 | * does not exist it's created. |
||
10170 | * |
||
10171 | * @static |
||
10172 | * @memberOf _ |
||
10173 | * @category Object |
||
10174 | * @param {Object} object The object to augment. |
||
10175 | * @param {Array|string} path The path of the property to set. |
||
10176 | * @param {*} value The value to set. |
||
10177 | * @returns {Object} Returns `object`. |
||
10178 | * @example |
||
10179 | * |
||
10180 | * var object = { 'a': [{ 'b': { 'c': 3 } }] }; |
||
10181 | * |
||
10182 | * _.set(object, 'a[0].b.c', 4); |
||
10183 | * console.log(object.a[0].b.c); |
||
10184 | * // => 4 |
||
10185 | * |
||
10186 | * _.set(object, 'x[0].y.z', 5); |
||
10187 | * console.log(object.x[0].y.z); |
||
10188 | * // => 5 |
||
10189 | */ |
||
10190 | function set(object, path, value) { |
||
10191 | if (object == null) { |
||
10192 | return object; |
||
10193 | } |
||
10194 | var pathKey = (path + ''); |
||
10195 | path = (object[pathKey] != null || isKey(path, object)) ? [pathKey] : toPath(path); |
||
10196 | |||
10197 | var index = -1, |
||
10198 | length = path.length, |
||
10199 | lastIndex = length - 1, |
||
10200 | nested = object; |
||
10201 | |||
10202 | while (nested != null && ++index < length) { |
||
10203 | var key = path[index]; |
||
10204 | if (isObject(nested)) { |
||
10205 | if (index == lastIndex) { |
||
10206 | nested[key] = value; |
||
10207 | } else if (nested[key] == null) { |
||
10208 | nested[key] = isIndex(path[index + 1]) ? [] : {}; |
||
10209 | } |
||
10210 | } |
||
10211 | nested = nested[key]; |
||
10212 | } |
||
10213 | return object; |
||
10214 | } |
||
10215 | |||
10216 | /** |
||
10217 | * An alternative to `_.reduce`; this method transforms `object` to a new |
||
10218 | * `accumulator` object which is the result of running each of its own enumerable |
||
10219 | * properties through `iteratee`, with each invocation potentially mutating |
||
10220 | * the `accumulator` object. The `iteratee` is bound to `thisArg` and invoked |
||
10221 | * with four arguments: (accumulator, value, key, object). Iteratee functions |
||
10222 | * may exit iteration early by explicitly returning `false`. |
||
10223 | * |
||
10224 | * @static |
||
10225 | * @memberOf _ |
||
10226 | * @category Object |
||
10227 | * @param {Array|Object} object The object to iterate over. |
||
10228 | * @param {Function} [iteratee=_.identity] The function invoked per iteration. |
||
10229 | * @param {*} [accumulator] The custom accumulator value. |
||
10230 | * @param {*} [thisArg] The `this` binding of `iteratee`. |
||
10231 | * @returns {*} Returns the accumulated value. |
||
10232 | * @example |
||
10233 | * |
||
10234 | * _.transform([2, 3, 4], function(result, n) { |
||
10235 | * result.push(n *= n); |
||
10236 | * return n % 2 == 0; |
||
10237 | * }); |
||
10238 | * // => [4, 9] |
||
10239 | * |
||
10240 | * _.transform({ 'a': 1, 'b': 2 }, function(result, n, key) { |
||
10241 | * result[key] = n * 3; |
||
10242 | * }); |
||
10243 | * // => { 'a': 3, 'b': 6 } |
||
10244 | */ |
||
10245 | function transform(object, iteratee, accumulator, thisArg) { |
||
10246 | var isArr = isArray(object) || isTypedArray(object); |
||
10247 | iteratee = getCallback(iteratee, thisArg, 4); |
||
10248 | |||
10249 | if (accumulator == null) { |
||
10250 | if (isArr || isObject(object)) { |
||
10251 | var Ctor = object.constructor; |
||
10252 | if (isArr) { |
||
10253 | accumulator = isArray(object) ? new Ctor : []; |
||
10254 | } else { |
||
10255 | accumulator = baseCreate(isFunction(Ctor) ? Ctor.prototype : undefined); |
||
10256 | } |
||
10257 | } else { |
||
10258 | accumulator = {}; |
||
10259 | } |
||
10260 | } |
||
10261 | (isArr ? arrayEach : baseForOwn)(object, function(value, index, object) { |
||
10262 | return iteratee(accumulator, value, index, object); |
||
10263 | }); |
||
10264 | return accumulator; |
||
10265 | } |
||
10266 | |||
10267 | /** |
||
10268 | * Creates an array of the own enumerable property values of `object`. |
||
10269 | * |
||
10270 | * **Note:** Non-object values are coerced to objects. |
||
10271 | * |
||
10272 | * @static |
||
10273 | * @memberOf _ |
||
10274 | * @category Object |
||
10275 | * @param {Object} object The object to query. |
||
10276 | * @returns {Array} Returns the array of property values. |
||
10277 | * @example |
||
10278 | * |
||
10279 | * function Foo() { |
||
10280 | * this.a = 1; |
||
10281 | * this.b = 2; |
||
10282 | * } |
||
10283 | * |
||
10284 | * Foo.prototype.c = 3; |
||
10285 | * |
||
10286 | * _.values(new Foo); |
||
10287 | * // => [1, 2] (iteration order is not guaranteed) |
||
10288 | * |
||
10289 | * _.values('hi'); |
||
10290 | * // => ['h', 'i'] |
||
10291 | */ |
||
10292 | function values(object) { |
||
10293 | return baseValues(object, keys(object)); |
||
10294 | } |
||
10295 | |||
10296 | /** |
||
10297 | * Creates an array of the own and inherited enumerable property values |
||
10298 | * of `object`. |
||
10299 | * |
||
10300 | * **Note:** Non-object values are coerced to objects. |
||
10301 | * |
||
10302 | * @static |
||
10303 | * @memberOf _ |
||
10304 | * @category Object |
||
10305 | * @param {Object} object The object to query. |
||
10306 | * @returns {Array} Returns the array of property values. |
||
10307 | * @example |
||
10308 | * |
||
10309 | * function Foo() { |
||
10310 | * this.a = 1; |
||
10311 | * this.b = 2; |
||
10312 | * } |
||
10313 | * |
||
10314 | * Foo.prototype.c = 3; |
||
10315 | * |
||
10316 | * _.valuesIn(new Foo); |
||
10317 | * // => [1, 2, 3] (iteration order is not guaranteed) |
||
10318 | */ |
||
10319 | function valuesIn(object) { |
||
10320 | return baseValues(object, keysIn(object)); |
||
10321 | } |
||
10322 | |||
10323 | /*------------------------------------------------------------------------*/ |
||
10324 | |||
10325 | /** |
||
10326 | * Checks if `n` is between `start` and up to but not including, `end`. If |
||
10327 | * `end` is not specified it's set to `start` with `start` then set to `0`. |
||
10328 | * |
||
10329 | * @static |
||
10330 | * @memberOf _ |
||
10331 | * @category Number |
||
10332 | * @param {number} n The number to check. |
||
10333 | * @param {number} [start=0] The start of the range. |
||
10334 | * @param {number} end The end of the range. |
||
10335 | * @returns {boolean} Returns `true` if `n` is in the range, else `false`. |
||
10336 | * @example |
||
10337 | * |
||
10338 | * _.inRange(3, 2, 4); |
||
10339 | * // => true |
||
10340 | * |
||
10341 | * _.inRange(4, 8); |
||
10342 | * // => true |
||
10343 | * |
||
10344 | * _.inRange(4, 2); |
||
10345 | * // => false |
||
10346 | * |
||
10347 | * _.inRange(2, 2); |
||
10348 | * // => false |
||
10349 | * |
||
10350 | * _.inRange(1.2, 2); |
||
10351 | * // => true |
||
10352 | * |
||
10353 | * _.inRange(5.2, 4); |
||
10354 | * // => false |
||
10355 | */ |
||
10356 | function inRange(value, start, end) { |
||
10357 | start = +start || 0; |
||
10358 | if (end === undefined) { |
||
10359 | end = start; |
||
10360 | start = 0; |
||
10361 | } else { |
||
10362 | end = +end || 0; |
||
10363 | } |
||
10364 | return value >= nativeMin(start, end) && value < nativeMax(start, end); |
||
10365 | } |
||
10366 | |||
10367 | /** |
||
10368 | * Produces a random number between `min` and `max` (inclusive). If only one |
||
10369 | * argument is provided a number between `0` and the given number is returned. |
||
10370 | * If `floating` is `true`, or either `min` or `max` are floats, a floating-point |
||
10371 | * number is returned instead of an integer. |
||
10372 | * |
||
10373 | * @static |
||
10374 | * @memberOf _ |
||
10375 | * @category Number |
||
10376 | * @param {number} [min=0] The minimum possible value. |
||
10377 | * @param {number} [max=1] The maximum possible value. |
||
10378 | * @param {boolean} [floating] Specify returning a floating-point number. |
||
10379 | * @returns {number} Returns the random number. |
||
10380 | * @example |
||
10381 | * |
||
10382 | * _.random(0, 5); |
||
10383 | * // => an integer between 0 and 5 |
||
10384 | * |
||
10385 | * _.random(5); |
||
10386 | * // => also an integer between 0 and 5 |
||
10387 | * |
||
10388 | * _.random(5, true); |
||
10389 | * // => a floating-point number between 0 and 5 |
||
10390 | * |
||
10391 | * _.random(1.2, 5.2); |
||
10392 | * // => a floating-point number between 1.2 and 5.2 |
||
10393 | */ |
||
10394 | function random(min, max, floating) { |
||
10395 | if (floating && isIterateeCall(min, max, floating)) { |
||
10396 | max = floating = undefined; |
||
10397 | } |
||
10398 | var noMin = min == null, |
||
10399 | noMax = max == null; |
||
10400 | |||
10401 | if (floating == null) { |
||
10402 | if (noMax && typeof min == 'boolean') { |
||
10403 | floating = min; |
||
10404 | min = 1; |
||
10405 | } |
||
10406 | else if (typeof max == 'boolean') { |
||
10407 | floating = max; |
||
10408 | noMax = true; |
||
10409 | } |
||
10410 | } |
||
10411 | if (noMin && noMax) { |
||
10412 | max = 1; |
||
10413 | noMax = false; |
||
10414 | } |
||
10415 | min = +min || 0; |
||
10416 | if (noMax) { |
||
10417 | max = min; |
||
10418 | min = 0; |
||
10419 | } else { |
||
10420 | max = +max || 0; |
||
10421 | } |
||
10422 | if (floating || min % 1 || max % 1) { |
||
10423 | var rand = nativeRandom(); |
||
10424 | return nativeMin(min + (rand * (max - min + parseFloat('1e-' + ((rand + '').length - 1)))), max); |
||
10425 | } |
||
10426 | return baseRandom(min, max); |
||
10427 | } |
||
10428 | |||
10429 | /*------------------------------------------------------------------------*/ |
||
10430 | |||
10431 | /** |
||
10432 | * Converts `string` to [camel case](https://en.wikipedia.org/wiki/CamelCase). |
||
10433 | * |
||
10434 | * @static |
||
10435 | * @memberOf _ |
||
10436 | * @category String |
||
10437 | * @param {string} [string=''] The string to convert. |
||
10438 | * @returns {string} Returns the camel cased string. |
||
10439 | * @example |
||
10440 | * |
||
10441 | * _.camelCase('Foo Bar'); |
||
10442 | * // => 'fooBar' |
||
10443 | * |
||
10444 | * _.camelCase('--foo-bar'); |
||
10445 | * // => 'fooBar' |
||
10446 | * |
||
10447 | * _.camelCase('__foo_bar__'); |
||
10448 | * // => 'fooBar' |
||
10449 | */ |
||
10450 | var camelCase = createCompounder(function(result, word, index) { |
||
10451 | word = word.toLowerCase(); |
||
10452 | return result + (index ? (word.charAt(0).toUpperCase() + word.slice(1)) : word); |
||
10453 | }); |
||
10454 | |||
10455 | /** |
||
10456 | * Capitalizes the first character of `string`. |
||
10457 | * |
||
10458 | * @static |
||
10459 | * @memberOf _ |
||
10460 | * @category String |
||
10461 | * @param {string} [string=''] The string to capitalize. |
||
10462 | * @returns {string} Returns the capitalized string. |
||
10463 | * @example |
||
10464 | * |
||
10465 | * _.capitalize('fred'); |
||
10466 | * // => 'Fred' |
||
10467 | */ |
||
10468 | function capitalize(string) { |
||
10469 | string = baseToString(string); |
||
10470 | return string && (string.charAt(0).toUpperCase() + string.slice(1)); |
||
10471 | } |
||
10472 | |||
10473 | /** |
||
10474 | * Deburrs `string` by converting [latin-1 supplementary letters](https://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block)#Character_table) |
||
10475 | * to basic latin letters and removing [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks). |
||
10476 | * |
||
10477 | * @static |
||
10478 | * @memberOf _ |
||
10479 | * @category String |
||
10480 | * @param {string} [string=''] The string to deburr. |
||
10481 | * @returns {string} Returns the deburred string. |
||
10482 | * @example |
||
10483 | * |
||
10484 | * _.deburr('déjà vu'); |
||
10485 | * // => 'deja vu' |
||
10486 | */ |
||
10487 | function deburr(string) { |
||
10488 | string = baseToString(string); |
||
10489 | return string && string.replace(reLatin1, deburrLetter).replace(reComboMark, ''); |
||
10490 | } |
||
10491 | |||
10492 | /** |
||
10493 | * Checks if `string` ends with the given target string. |
||
10494 | * |
||
10495 | * @static |
||
10496 | * @memberOf _ |
||
10497 | * @category String |
||
10498 | * @param {string} [string=''] The string to search. |
||
10499 | * @param {string} [target] The string to search for. |
||
10500 | * @param {number} [position=string.length] The position to search from. |
||
10501 | * @returns {boolean} Returns `true` if `string` ends with `target`, else `false`. |
||
10502 | * @example |
||
10503 | * |
||
10504 | * _.endsWith('abc', 'c'); |
||
10505 | * // => true |
||
10506 | * |
||
10507 | * _.endsWith('abc', 'b'); |
||
10508 | * // => false |
||
10509 | * |
||
10510 | * _.endsWith('abc', 'b', 2); |
||
10511 | * // => true |
||
10512 | */ |
||
10513 | function endsWith(string, target, position) { |
||
10514 | string = baseToString(string); |
||
10515 | target = (target + ''); |
||
10516 | |||
10517 | var length = string.length; |
||
10518 | position = position === undefined |
||
10519 | ? length |
||
10520 | : nativeMin(position < 0 ? 0 : (+position || 0), length); |
||
10521 | |||
10522 | position -= target.length; |
||
10523 | return position >= 0 && string.indexOf(target, position) == position; |
||
10524 | } |
||
10525 | |||
10526 | /** |
||
10527 | * Converts the characters "&", "<", ">", '"', "'", and "\`", in `string` to |
||
10528 | * their corresponding HTML entities. |
||
10529 | * |
||
10530 | * **Note:** No other characters are escaped. To escape additional characters |
||
10531 | * use a third-party library like [_he_](https://mths.be/he). |
||
10532 | * |
||
10533 | * Though the ">" character is escaped for symmetry, characters like |
||
10534 | * ">" and "/" don't need escaping in HTML and have no special meaning |
||
10535 | * unless they're part of a tag or unquoted attribute value. |
||
10536 | * See [Mathias Bynens's article](https://mathiasbynens.be/notes/ambiguous-ampersands) |
||
10537 | * (under "semi-related fun fact") for more details. |
||
10538 | * |
||
10539 | * Backticks are escaped because in Internet Explorer < 9, they can break out |
||
10540 | * of attribute values or HTML comments. See [#59](https://html5sec.org/#59), |
||
10541 | * [#102](https://html5sec.org/#102), [#108](https://html5sec.org/#108), and |
||
10542 | * [#133](https://html5sec.org/#133) of the [HTML5 Security Cheatsheet](https://html5sec.org/) |
||
10543 | * for more details. |
||
10544 | * |
||
10545 | * When working with HTML you should always [quote attribute values](http://wonko.com/post/html-escaping) |
||
10546 | * to reduce XSS vectors. |
||
10547 | * |
||
10548 | * @static |
||
10549 | * @memberOf _ |
||
10550 | * @category String |
||
10551 | * @param {string} [string=''] The string to escape. |
||
10552 | * @returns {string} Returns the escaped string. |
||
10553 | * @example |
||
10554 | * |
||
10555 | * _.escape('fred, barney, & pebbles'); |
||
10556 | * // => 'fred, barney, & pebbles' |
||
10557 | */ |
||
10558 | function escape(string) { |
||
10559 | // Reset `lastIndex` because in IE < 9 `String#replace` does not. |
||
10560 | string = baseToString(string); |
||
10561 | return (string && reHasUnescapedHtml.test(string)) |
||
10562 | ? string.replace(reUnescapedHtml, escapeHtmlChar) |
||
10563 | : string; |
||
10564 | } |
||
10565 | |||
10566 | /** |
||
10567 | * Escapes the `RegExp` special characters "\", "/", "^", "$", ".", "|", "?", |
||
10568 | * "*", "+", "(", ")", "[", "]", "{" and "}" in `string`. |
||
10569 | * |
||
10570 | * @static |
||
10571 | * @memberOf _ |
||
10572 | * @category String |
||
10573 | * @param {string} [string=''] The string to escape. |
||
10574 | * @returns {string} Returns the escaped string. |
||
10575 | * @example |
||
10576 | * |
||
10577 | * _.escapeRegExp('[lodash](https://lodash.com/)'); |
||
10578 | * // => '\[lodash\]\(https:\/\/lodash\.com\/\)' |
||
10579 | */ |
||
10580 | function escapeRegExp(string) { |
||
10581 | string = baseToString(string); |
||
10582 | return (string && reHasRegExpChars.test(string)) |
||
10583 | ? string.replace(reRegExpChars, escapeRegExpChar) |
||
10584 | : (string || '(?:)'); |
||
10585 | } |
||
10586 | |||
10587 | /** |
||
10588 | * Converts `string` to [kebab case](https://en.wikipedia.org/wiki/Letter_case#Special_case_styles). |
||
10589 | * |
||
10590 | * @static |
||
10591 | * @memberOf _ |
||
10592 | * @category String |
||
10593 | * @param {string} [string=''] The string to convert. |
||
10594 | * @returns {string} Returns the kebab cased string. |
||
10595 | * @example |
||
10596 | * |
||
10597 | * _.kebabCase('Foo Bar'); |
||
10598 | * // => 'foo-bar' |
||
10599 | * |
||
10600 | * _.kebabCase('fooBar'); |
||
10601 | * // => 'foo-bar' |
||
10602 | * |
||
10603 | * _.kebabCase('__foo_bar__'); |
||
10604 | * // => 'foo-bar' |
||
10605 | */ |
||
10606 | var kebabCase = createCompounder(function(result, word, index) { |
||
10607 | return result + (index ? '-' : '') + word.toLowerCase(); |
||
10608 | }); |
||
10609 | |||
10610 | /** |
||
10611 | * Pads `string` on the left and right sides if it's shorter than `length`. |
||
10612 | * Padding characters are truncated if they can't be evenly divided by `length`. |
||
10613 | * |
||
10614 | * @static |
||
10615 | * @memberOf _ |
||
10616 | * @category String |
||
10617 | * @param {string} [string=''] The string to pad. |
||
10618 | * @param {number} [length=0] The padding length. |
||
10619 | * @param {string} [chars=' '] The string used as padding. |
||
10620 | * @returns {string} Returns the padded string. |
||
10621 | * @example |
||
10622 | * |
||
10623 | * _.pad('abc', 8); |
||
10624 | * // => ' abc ' |
||
10625 | * |
||
10626 | * _.pad('abc', 8, '_-'); |
||
10627 | * // => '_-abc_-_' |
||
10628 | * |
||
10629 | * _.pad('abc', 3); |
||
10630 | * // => 'abc' |
||
10631 | */ |
||
10632 | function pad(string, length, chars) { |
||
10633 | string = baseToString(string); |
||
10634 | length = +length; |
||
10635 | |||
10636 | var strLength = string.length; |
||
10637 | if (strLength >= length || !nativeIsFinite(length)) { |
||
10638 | return string; |
||
10639 | } |
||
10640 | var mid = (length - strLength) / 2, |
||
10641 | leftLength = nativeFloor(mid), |
||
10642 | rightLength = nativeCeil(mid); |
||
10643 | |||
10644 | chars = createPadding('', rightLength, chars); |
||
10645 | return chars.slice(0, leftLength) + string + chars; |
||
10646 | } |
||
10647 | |||
10648 | /** |
||
10649 | * Pads `string` on the left side if it's shorter than `length`. Padding |
||
10650 | * characters are truncated if they exceed `length`. |
||
10651 | * |
||
10652 | * @static |
||
10653 | * @memberOf _ |
||
10654 | * @category String |
||
10655 | * @param {string} [string=''] The string to pad. |
||
10656 | * @param {number} [length=0] The padding length. |
||
10657 | * @param {string} [chars=' '] The string used as padding. |
||
10658 | * @returns {string} Returns the padded string. |
||
10659 | * @example |
||
10660 | * |
||
10661 | * _.padLeft('abc', 6); |
||
10662 | * // => ' abc' |
||
10663 | * |
||
10664 | * _.padLeft('abc', 6, '_-'); |
||
10665 | * // => '_-_abc' |
||
10666 | * |
||
10667 | * _.padLeft('abc', 3); |
||
10668 | * // => 'abc' |
||
10669 | */ |
||
10670 | var padLeft = createPadDir(); |
||
10671 | |||
10672 | /** |
||
10673 | * Pads `string` on the right side if it's shorter than `length`. Padding |
||
10674 | * characters are truncated if they exceed `length`. |
||
10675 | * |
||
10676 | * @static |
||
10677 | * @memberOf _ |
||
10678 | * @category String |
||
10679 | * @param {string} [string=''] The string to pad. |
||
10680 | * @param {number} [length=0] The padding length. |
||
10681 | * @param {string} [chars=' '] The string used as padding. |
||
10682 | * @returns {string} Returns the padded string. |
||
10683 | * @example |
||
10684 | * |
||
10685 | * _.padRight('abc', 6); |
||
10686 | * // => 'abc ' |
||
10687 | * |
||
10688 | * _.padRight('abc', 6, '_-'); |
||
10689 | * // => 'abc_-_' |
||
10690 | * |
||
10691 | * _.padRight('abc', 3); |
||
10692 | * // => 'abc' |
||
10693 | */ |
||
10694 | var padRight = createPadDir(true); |
||
10695 | |||
10696 | /** |
||
10697 | * Converts `string` to an integer of the specified radix. If `radix` is |
||
10698 | * `undefined` or `0`, a `radix` of `10` is used unless `value` is a hexadecimal, |
||
10699 | * in which case a `radix` of `16` is used. |
||
10700 | * |
||
10701 | * **Note:** This method aligns with the [ES5 implementation](https://es5.github.io/#E) |
||
10702 | * of `parseInt`. |
||
10703 | * |
||
10704 | * @static |
||
10705 | * @memberOf _ |
||
10706 | * @category String |
||
10707 | * @param {string} string The string to convert. |
||
10708 | * @param {number} [radix] The radix to interpret `value` by. |
||
10709 | * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. |
||
10710 | * @returns {number} Returns the converted integer. |
||
10711 | * @example |
||
10712 | * |
||
10713 | * _.parseInt('08'); |
||
10714 | * // => 8 |
||
10715 | * |
||
10716 | * _.map(['6', '08', '10'], _.parseInt); |
||
10717 | * // => [6, 8, 10] |
||
10718 | */ |
||
10719 | function parseInt(string, radix, guard) { |
||
10720 | // Firefox < 21 and Opera < 15 follow ES3 for `parseInt`. |
||
10721 | // Chrome fails to trim leading <BOM> whitespace characters. |
||
10722 | // See https://code.google.com/p/v8/issues/detail?id=3109 for more details. |
||
10723 | if (guard ? isIterateeCall(string, radix, guard) : radix == null) { |
||
10724 | radix = 0; |
||
10725 | } else if (radix) { |
||
10726 | radix = +radix; |
||
10727 | } |
||
10728 | string = trim(string); |
||
10729 | return nativeParseInt(string, radix || (reHasHexPrefix.test(string) ? 16 : 10)); |
||
10730 | } |
||
10731 | |||
10732 | /** |
||
10733 | * Repeats the given string `n` times. |
||
10734 | * |
||
10735 | * @static |
||
10736 | * @memberOf _ |
||
10737 | * @category String |
||
10738 | * @param {string} [string=''] The string to repeat. |
||
10739 | * @param {number} [n=0] The number of times to repeat the string. |
||
10740 | * @returns {string} Returns the repeated string. |
||
10741 | * @example |
||
10742 | * |
||
10743 | * _.repeat('*', 3); |
||
10744 | * // => '***' |
||
10745 | * |
||
10746 | * _.repeat('abc', 2); |
||
10747 | * // => 'abcabc' |
||
10748 | * |
||
10749 | * _.repeat('abc', 0); |
||
10750 | * // => '' |
||
10751 | */ |
||
10752 | function repeat(string, n) { |
||
10753 | var result = ''; |
||
10754 | string = baseToString(string); |
||
10755 | n = +n; |
||
10756 | if (n < 1 || !string || !nativeIsFinite(n)) { |
||
10757 | return result; |
||
10758 | } |
||
10759 | // Leverage the exponentiation by squaring algorithm for a faster repeat. |
||
10760 | // See https://en.wikipedia.org/wiki/Exponentiation_by_squaring for more details. |
||
10761 | do { |
||
10762 | if (n % 2) { |
||
10763 | result += string; |
||
10764 | } |
||
10765 | n = nativeFloor(n / 2); |
||
10766 | string += string; |
||
10767 | } while (n); |
||
10768 | |||
10769 | return result; |
||
10770 | } |
||
10771 | |||
10772 | /** |
||
10773 | * Converts `string` to [snake case](https://en.wikipedia.org/wiki/Snake_case). |
||
10774 | * |
||
10775 | * @static |
||
10776 | * @memberOf _ |
||
10777 | * @category String |
||
10778 | * @param {string} [string=''] The string to convert. |
||
10779 | * @returns {string} Returns the snake cased string. |
||
10780 | * @example |
||
10781 | * |
||
10782 | * _.snakeCase('Foo Bar'); |
||
10783 | * // => 'foo_bar' |
||
10784 | * |
||
10785 | * _.snakeCase('fooBar'); |
||
10786 | * // => 'foo_bar' |
||
10787 | * |
||
10788 | * _.snakeCase('--foo-bar'); |
||
10789 | * // => 'foo_bar' |
||
10790 | */ |
||
10791 | var snakeCase = createCompounder(function(result, word, index) { |
||
10792 | return result + (index ? '_' : '') + word.toLowerCase(); |
||
10793 | }); |
||
10794 | |||
10795 | /** |
||
10796 | * Converts `string` to [start case](https://en.wikipedia.org/wiki/Letter_case#Stylistic_or_specialised_usage). |
||
10797 | * |
||
10798 | * @static |
||
10799 | * @memberOf _ |
||
10800 | * @category String |
||
10801 | * @param {string} [string=''] The string to convert. |
||
10802 | * @returns {string} Returns the start cased string. |
||
10803 | * @example |
||
10804 | * |
||
10805 | * _.startCase('--foo-bar'); |
||
10806 | * // => 'Foo Bar' |
||
10807 | * |
||
10808 | * _.startCase('fooBar'); |
||
10809 | * // => 'Foo Bar' |
||
10810 | * |
||
10811 | * _.startCase('__foo_bar__'); |
||
10812 | * // => 'Foo Bar' |
||
10813 | */ |
||
10814 | var startCase = createCompounder(function(result, word, index) { |
||
10815 | return result + (index ? ' ' : '') + (word.charAt(0).toUpperCase() + word.slice(1)); |
||
10816 | }); |
||
10817 | |||
10818 | /** |
||
10819 | * Checks if `string` starts with the given target string. |
||
10820 | * |
||
10821 | * @static |
||
10822 | * @memberOf _ |
||
10823 | * @category String |
||
10824 | * @param {string} [string=''] The string to search. |
||
10825 | * @param {string} [target] The string to search for. |
||
10826 | * @param {number} [position=0] The position to search from. |
||
10827 | * @returns {boolean} Returns `true` if `string` starts with `target`, else `false`. |
||
10828 | * @example |
||
10829 | * |
||
10830 | * _.startsWith('abc', 'a'); |
||
10831 | * // => true |
||
10832 | * |
||
10833 | * _.startsWith('abc', 'b'); |
||
10834 | * // => false |
||
10835 | * |
||
10836 | * _.startsWith('abc', 'b', 1); |
||
10837 | * // => true |
||
10838 | */ |
||
10839 | function startsWith(string, target, position) { |
||
10840 | string = baseToString(string); |
||
10841 | position = position == null |
||
10842 | ? 0 |
||
10843 | : nativeMin(position < 0 ? 0 : (+position || 0), string.length); |
||
10844 | |||
10845 | return string.lastIndexOf(target, position) == position; |
||
10846 | } |
||
10847 | |||
10848 | /** |
||
10849 | * Creates a compiled template function that can interpolate data properties |
||
10850 | * in "interpolate" delimiters, HTML-escape interpolated data properties in |
||
10851 | * "escape" delimiters, and execute JavaScript in "evaluate" delimiters. Data |
||
10852 | * properties may be accessed as free variables in the template. If a setting |
||
10853 | * object is provided it takes precedence over `_.templateSettings` values. |
||
10854 | * |
||
10855 | * **Note:** In the development build `_.template` utilizes |
||
10856 | * [sourceURLs](http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl) |
||
10857 | * for easier debugging. |
||
10858 | * |
||
10859 | * For more information on precompiling templates see |
||
10860 | * [lodash's custom builds documentation](https://lodash.com/custom-builds). |
||
10861 | * |
||
10862 | * For more information on Chrome extension sandboxes see |
||
10863 | * [Chrome's extensions documentation](https://developer.chrome.com/extensions/sandboxingEval). |
||
10864 | * |
||
10865 | * @static |
||
10866 | * @memberOf _ |
||
10867 | * @category String |
||
10868 | * @param {string} [string=''] The template string. |
||
10869 | * @param {Object} [options] The options object. |
||
10870 | * @param {RegExp} [options.escape] The HTML "escape" delimiter. |
||
10871 | * @param {RegExp} [options.evaluate] The "evaluate" delimiter. |
||
10872 | * @param {Object} [options.imports] An object to import into the template as free variables. |
||
10873 | * @param {RegExp} [options.interpolate] The "interpolate" delimiter. |
||
10874 | * @param {string} [options.sourceURL] The sourceURL of the template's compiled source. |
||
10875 | * @param {string} [options.variable] The data object variable name. |
||
10876 | * @param- {Object} [otherOptions] Enables the legacy `options` param signature. |
||
10877 | * @returns {Function} Returns the compiled template function. |
||
10878 | * @example |
||
10879 | * |
||
10880 | * // using the "interpolate" delimiter to create a compiled template |
||
10881 | * var compiled = _.template('hello <%= user %>!'); |
||
10882 | * compiled({ 'user': 'fred' }); |
||
10883 | * // => 'hello fred!' |
||
10884 | * |
||
10885 | * // using the HTML "escape" delimiter to escape data property values |
||
10886 | * var compiled = _.template('<b><%- value %></b>'); |
||
10887 | * compiled({ 'value': '<script>' }); |
||
10888 | * // => '<b><script></b>' |
||
10889 | * |
||
10890 | * // using the "evaluate" delimiter to execute JavaScript and generate HTML |
||
10891 | * var compiled = _.template('<% _.forEach(users, function(user) { %><li><%- user %></li><% }); %>'); |
||
10892 | * compiled({ 'users': ['fred', 'barney'] }); |
||
10893 | * // => '<li>fred</li><li>barney</li>' |
||
10894 | * |
||
10895 | * // using the internal `print` function in "evaluate" delimiters |
||
10896 | * var compiled = _.template('<% print("hello " + user); %>!'); |
||
10897 | * compiled({ 'user': 'barney' }); |
||
10898 | * // => 'hello barney!' |
||
10899 | * |
||
10900 | * // using the ES delimiter as an alternative to the default "interpolate" delimiter |
||
10901 | * var compiled = _.template('hello ${ user }!'); |
||
10902 | * compiled({ 'user': 'pebbles' }); |
||
10903 | * // => 'hello pebbles!' |
||
10904 | * |
||
10905 | * // using custom template delimiters |
||
10906 | * _.templateSettings.interpolate = /{{([\s\S]+?)}}/g; |
||
10907 | * var compiled = _.template('hello {{ user }}!'); |
||
10908 | * compiled({ 'user': 'mustache' }); |
||
10909 | * // => 'hello mustache!' |
||
10910 | * |
||
10911 | * // using backslashes to treat delimiters as plain text |
||
10912 | * var compiled = _.template('<%= "\\<%- value %\\>" %>'); |
||
10913 | * compiled({ 'value': 'ignored' }); |
||
10914 | * // => '<%- value %>' |
||
10915 | * |
||
10916 | * // using the `imports` option to import `jQuery` as `jq` |
||
10917 | * var text = '<% jq.each(users, function(user) { %><li><%- user %></li><% }); %>'; |
||
10918 | * var compiled = _.template(text, { 'imports': { 'jq': jQuery } }); |
||
10919 | * compiled({ 'users': ['fred', 'barney'] }); |
||
10920 | * // => '<li>fred</li><li>barney</li>' |
||
10921 | * |
||
10922 | * // using the `sourceURL` option to specify a custom sourceURL for the template |
||
10923 | * var compiled = _.template('hello <%= user %>!', { 'sourceURL': '/basic/greeting.jst' }); |
||
10924 | * compiled(data); |
||
10925 | * // => find the source of "greeting.jst" under the Sources tab or Resources panel of the web inspector |
||
10926 | * |
||
10927 | * // using the `variable` option to ensure a with-statement isn't used in the compiled template |
||
10928 | * var compiled = _.template('hi <%= data.user %>!', { 'variable': 'data' }); |
||
10929 | * compiled.source; |
||
10930 | * // => function(data) { |
||
10931 | * // var __t, __p = ''; |
||
10932 | * // __p += 'hi ' + ((__t = ( data.user )) == null ? '' : __t) + '!'; |
||
10933 | * // return __p; |
||
10934 | * // } |
||
10935 | * |
||
10936 | * // using the `source` property to inline compiled templates for meaningful |
||
10937 | * // line numbers in error messages and a stack trace |
||
10938 | * fs.writeFileSync(path.join(cwd, 'jst.js'), '\ |
||
10939 | * var JST = {\ |
||
10940 | * "main": ' + _.template(mainText).source + '\ |
||
10941 | * };\ |
||
10942 | * '); |
||
10943 | */ |
||
10944 | function template(string, options, otherOptions) { |
||
10945 | // Based on John Resig's `tmpl` implementation (http://ejohn.org/blog/javascript-micro-templating/) |
||
10946 | // and Laura Doktorova's doT.js (https://github.com/olado/doT). |
||
10947 | var settings = lodash.templateSettings; |
||
10948 | |||
10949 | if (otherOptions && isIterateeCall(string, options, otherOptions)) { |
||
10950 | options = otherOptions = undefined; |
||
10951 | } |
||
10952 | string = baseToString(string); |
||
10953 | options = assignWith(baseAssign({}, otherOptions || options), settings, assignOwnDefaults); |
||
10954 | |||
10955 | var imports = assignWith(baseAssign({}, options.imports), settings.imports, assignOwnDefaults), |
||
10956 | importsKeys = keys(imports), |
||
10957 | importsValues = baseValues(imports, importsKeys); |
||
10958 | |||
10959 | var isEscaping, |
||
10960 | isEvaluating, |
||
10961 | index = 0, |
||
10962 | interpolate = options.interpolate || reNoMatch, |
||
10963 | source = "__p += '"; |
||
10964 | |||
10965 | // Compile the regexp to match each delimiter. |
||
10966 | var reDelimiters = RegExp( |
||
10967 | (options.escape || reNoMatch).source + '|' + |
||
10968 | interpolate.source + '|' + |
||
10969 | (interpolate === reInterpolate ? reEsTemplate : reNoMatch).source + '|' + |
||
10970 | (options.evaluate || reNoMatch).source + '|$' |
||
10971 | , 'g'); |
||
10972 | |||
10973 | // Use a sourceURL for easier debugging. |
||
10974 | var sourceURL = '//# sourceURL=' + |
||
10975 | ('sourceURL' in options |
||
10976 | ? options.sourceURL |
||
10977 | : ('lodash.templateSources[' + (++templateCounter) + ']') |
||
10978 | ) + '\n'; |
||
10979 | |||
10980 | string.replace(reDelimiters, function(match, escapeValue, interpolateValue, esTemplateValue, evaluateValue, offset) { |
||
10981 | interpolateValue || (interpolateValue = esTemplateValue); |
||
10982 | |||
10983 | // Escape characters that can't be included in string literals. |
||
10984 | source += string.slice(index, offset).replace(reUnescapedString, escapeStringChar); |
||
10985 | |||
10986 | // Replace delimiters with snippets. |
||
10987 | if (escapeValue) { |
||
10988 | isEscaping = true; |
||
10989 | source += "' +\n__e(" + escapeValue + ") +\n'"; |
||
10990 | } |
||
10991 | if (evaluateValue) { |
||
10992 | isEvaluating = true; |
||
10993 | source += "';\n" + evaluateValue + ";\n__p += '"; |
||
10994 | } |
||
10995 | if (interpolateValue) { |
||
10996 | source += "' +\n((__t = (" + interpolateValue + ")) == null ? '' : __t) +\n'"; |
||
10997 | } |
||
10998 | index = offset + match.length; |
||
10999 | |||
11000 | // The JS engine embedded in Adobe products requires returning the `match` |
||
11001 | // string in order to produce the correct `offset` value. |
||
11002 | return match; |
||
11003 | }); |
||
11004 | |||
11005 | source += "';\n"; |
||
11006 | |||
11007 | // If `variable` is not specified wrap a with-statement around the generated |
||
11008 | // code to add the data object to the top of the scope chain. |
||
11009 | var variable = options.variable; |
||
11010 | if (!variable) { |
||
11011 | source = 'with (obj) {\n' + source + '\n}\n'; |
||
11012 | } |
||
11013 | // Cleanup code by stripping empty strings. |
||
11014 | source = (isEvaluating ? source.replace(reEmptyStringLeading, '') : source) |
||
11015 | .replace(reEmptyStringMiddle, '$1') |
||
11016 | .replace(reEmptyStringTrailing, '$1;'); |
||
11017 | |||
11018 | // Frame code as the function body. |
||
11019 | source = 'function(' + (variable || 'obj') + ') {\n' + |
||
11020 | (variable |
||
11021 | ? '' |
||
11022 | : 'obj || (obj = {});\n' |
||
11023 | ) + |
||
11024 | "var __t, __p = ''" + |
||
11025 | (isEscaping |
||
11026 | ? ', __e = _.escape' |
||
11027 | : '' |
||
11028 | ) + |
||
11029 | (isEvaluating |
||
11030 | ? ', __j = Array.prototype.join;\n' + |
||
11031 | "function print() { __p += __j.call(arguments, '') }\n" |
||
11032 | : ';\n' |
||
11033 | ) + |
||
11034 | source + |
||
11035 | 'return __p\n}'; |
||
11036 | |||
11037 | var result = attempt(function() { |
||
11038 | return Function(importsKeys, sourceURL + 'return ' + source).apply(undefined, importsValues); |
||
11039 | }); |
||
11040 | |||
11041 | // Provide the compiled function's source by its `toString` method or |
||
11042 | // the `source` property as a convenience for inlining compiled templates. |
||
11043 | result.source = source; |
||
11044 | if (isError(result)) { |
||
11045 | throw result; |
||
11046 | } |
||
11047 | return result; |
||
11048 | } |
||
11049 | |||
11050 | /** |
||
11051 | * Removes leading and trailing whitespace or specified characters from `string`. |
||
11052 | * |
||
11053 | * @static |
||
11054 | * @memberOf _ |
||
11055 | * @category String |
||
11056 | * @param {string} [string=''] The string to trim. |
||
11057 | * @param {string} [chars=whitespace] The characters to trim. |
||
11058 | * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. |
||
11059 | * @returns {string} Returns the trimmed string. |
||
11060 | * @example |
||
11061 | * |
||
11062 | * _.trim(' abc '); |
||
11063 | * // => 'abc' |
||
11064 | * |
||
11065 | * _.trim('-_-abc-_-', '_-'); |
||
11066 | * // => 'abc' |
||
11067 | * |
||
11068 | * _.map([' foo ', ' bar '], _.trim); |
||
11069 | * // => ['foo', 'bar'] |
||
11070 | */ |
||
11071 | function trim(string, chars, guard) { |
||
11072 | var value = string; |
||
11073 | string = baseToString(string); |
||
11074 | if (!string) { |
||
11075 | return string; |
||
11076 | } |
||
11077 | if (guard ? isIterateeCall(value, chars, guard) : chars == null) { |
||
11078 | return string.slice(trimmedLeftIndex(string), trimmedRightIndex(string) + 1); |
||
11079 | } |
||
11080 | chars = (chars + ''); |
||
11081 | return string.slice(charsLeftIndex(string, chars), charsRightIndex(string, chars) + 1); |
||
11082 | } |
||
11083 | |||
11084 | /** |
||
11085 | * Removes leading whitespace or specified characters from `string`. |
||
11086 | * |
||
11087 | * @static |
||
11088 | * @memberOf _ |
||
11089 | * @category String |
||
11090 | * @param {string} [string=''] The string to trim. |
||
11091 | * @param {string} [chars=whitespace] The characters to trim. |
||
11092 | * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. |
||
11093 | * @returns {string} Returns the trimmed string. |
||
11094 | * @example |
||
11095 | * |
||
11096 | * _.trimLeft(' abc '); |
||
11097 | * // => 'abc ' |
||
11098 | * |
||
11099 | * _.trimLeft('-_-abc-_-', '_-'); |
||
11100 | * // => 'abc-_-' |
||
11101 | */ |
||
11102 | function trimLeft(string, chars, guard) { |
||
11103 | var value = string; |
||
11104 | string = baseToString(string); |
||
11105 | if (!string) { |
||
11106 | return string; |
||
11107 | } |
||
11108 | if (guard ? isIterateeCall(value, chars, guard) : chars == null) { |
||
11109 | return string.slice(trimmedLeftIndex(string)); |
||
11110 | } |
||
11111 | return string.slice(charsLeftIndex(string, (chars + ''))); |
||
11112 | } |
||
11113 | |||
11114 | /** |
||
11115 | * Removes trailing whitespace or specified characters from `string`. |
||
11116 | * |
||
11117 | * @static |
||
11118 | * @memberOf _ |
||
11119 | * @category String |
||
11120 | * @param {string} [string=''] The string to trim. |
||
11121 | * @param {string} [chars=whitespace] The characters to trim. |
||
11122 | * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. |
||
11123 | * @returns {string} Returns the trimmed string. |
||
11124 | * @example |
||
11125 | * |
||
11126 | * _.trimRight(' abc '); |
||
11127 | * // => ' abc' |
||
11128 | * |
||
11129 | * _.trimRight('-_-abc-_-', '_-'); |
||
11130 | * // => '-_-abc' |
||
11131 | */ |
||
11132 | function trimRight(string, chars, guard) { |
||
11133 | var value = string; |
||
11134 | string = baseToString(string); |
||
11135 | if (!string) { |
||
11136 | return string; |
||
11137 | } |
||
11138 | if (guard ? isIterateeCall(value, chars, guard) : chars == null) { |
||
11139 | return string.slice(0, trimmedRightIndex(string) + 1); |
||
11140 | } |
||
11141 | return string.slice(0, charsRightIndex(string, (chars + '')) + 1); |
||
11142 | } |
||
11143 | |||
11144 | /** |
||
11145 | * Truncates `string` if it's longer than the given maximum string length. |
||
11146 | * The last characters of the truncated string are replaced with the omission |
||
11147 | * string which defaults to "...". |
||
11148 | * |
||
11149 | * @static |
||
11150 | * @memberOf _ |
||
11151 | * @category String |
||
11152 | * @param {string} [string=''] The string to truncate. |
||
11153 | * @param {Object|number} [options] The options object or maximum string length. |
||
11154 | * @param {number} [options.length=30] The maximum string length. |
||
11155 | * @param {string} [options.omission='...'] The string to indicate text is omitted. |
||
11156 | * @param {RegExp|string} [options.separator] The separator pattern to truncate to. |
||
11157 | * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. |
||
11158 | * @returns {string} Returns the truncated string. |
||
11159 | * @example |
||
11160 | * |
||
11161 | * _.trunc('hi-diddly-ho there, neighborino'); |
||
11162 | * // => 'hi-diddly-ho there, neighbo...' |
||
11163 | * |
||
11164 | * _.trunc('hi-diddly-ho there, neighborino', 24); |
||
11165 | * // => 'hi-diddly-ho there, n...' |
||
11166 | * |
||
11167 | * _.trunc('hi-diddly-ho there, neighborino', { |
||
11168 | * 'length': 24, |
||
11169 | * 'separator': ' ' |
||
11170 | * }); |
||
11171 | * // => 'hi-diddly-ho there,...' |
||
11172 | * |
||
11173 | * _.trunc('hi-diddly-ho there, neighborino', { |
||
11174 | * 'length': 24, |
||
11175 | * 'separator': /,? +/ |
||
11176 | * }); |
||
11177 | * // => 'hi-diddly-ho there...' |
||
11178 | * |
||
11179 | * _.trunc('hi-diddly-ho there, neighborino', { |
||
11180 | * 'omission': ' [...]' |
||
11181 | * }); |
||
11182 | * // => 'hi-diddly-ho there, neig [...]' |
||
11183 | */ |
||
11184 | function trunc(string, options, guard) { |
||
11185 | if (guard && isIterateeCall(string, options, guard)) { |
||
11186 | options = undefined; |
||
11187 | } |
||
11188 | var length = DEFAULT_TRUNC_LENGTH, |
||
11189 | omission = DEFAULT_TRUNC_OMISSION; |
||
11190 | |||
11191 | if (options != null) { |
||
11192 | if (isObject(options)) { |
||
11193 | var separator = 'separator' in options ? options.separator : separator; |
||
11194 | length = 'length' in options ? (+options.length || 0) : length; |
||
11195 | omission = 'omission' in options ? baseToString(options.omission) : omission; |
||
11196 | } else { |
||
11197 | length = +options || 0; |
||
11198 | } |
||
11199 | } |
||
11200 | string = baseToString(string); |
||
11201 | if (length >= string.length) { |
||
11202 | return string; |
||
11203 | } |
||
11204 | var end = length - omission.length; |
||
11205 | if (end < 1) { |
||
11206 | return omission; |
||
11207 | } |
||
11208 | var result = string.slice(0, end); |
||
11209 | if (separator == null) { |
||
11210 | return result + omission; |
||
11211 | } |
||
11212 | if (isRegExp(separator)) { |
||
11213 | if (string.slice(end).search(separator)) { |
||
11214 | var match, |
||
11215 | newEnd, |
||
11216 | substring = string.slice(0, end); |
||
11217 | |||
11218 | if (!separator.global) { |
||
11219 | separator = RegExp(separator.source, (reFlags.exec(separator) || '') + 'g'); |
||
11220 | } |
||
11221 | separator.lastIndex = 0; |
||
11222 | while ((match = separator.exec(substring))) { |
||
11223 | newEnd = match.index; |
||
11224 | } |
||
11225 | result = result.slice(0, newEnd == null ? end : newEnd); |
||
11226 | } |
||
11227 | } else if (string.indexOf(separator, end) != end) { |
||
11228 | var index = result.lastIndexOf(separator); |
||
11229 | if (index > -1) { |
||
11230 | result = result.slice(0, index); |
||
11231 | } |
||
11232 | } |
||
11233 | return result + omission; |
||
11234 | } |
||
11235 | |||
11236 | /** |
||
11237 | * The inverse of `_.escape`; this method converts the HTML entities |
||
11238 | * `&`, `<`, `>`, `"`, `'`, and ``` in `string` to their |
||
11239 | * corresponding characters. |
||
11240 | * |
||
11241 | * **Note:** No other HTML entities are unescaped. To unescape additional HTML |
||
11242 | * entities use a third-party library like [_he_](https://mths.be/he). |
||
11243 | * |
||
11244 | * @static |
||
11245 | * @memberOf _ |
||
11246 | * @category String |
||
11247 | * @param {string} [string=''] The string to unescape. |
||
11248 | * @returns {string} Returns the unescaped string. |
||
11249 | * @example |
||
11250 | * |
||
11251 | * _.unescape('fred, barney, & pebbles'); |
||
11252 | * // => 'fred, barney, & pebbles' |
||
11253 | */ |
||
11254 | function unescape(string) { |
||
11255 | string = baseToString(string); |
||
11256 | return (string && reHasEscapedHtml.test(string)) |
||
11257 | ? string.replace(reEscapedHtml, unescapeHtmlChar) |
||
11258 | : string; |
||
11259 | } |
||
11260 | |||
11261 | /** |
||
11262 | * Splits `string` into an array of its words. |
||
11263 | * |
||
11264 | * @static |
||
11265 | * @memberOf _ |
||
11266 | * @category String |
||
11267 | * @param {string} [string=''] The string to inspect. |
||
11268 | * @param {RegExp|string} [pattern] The pattern to match words. |
||
11269 | * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. |
||
11270 | * @returns {Array} Returns the words of `string`. |
||
11271 | * @example |
||
11272 | * |
||
11273 | * _.words('fred, barney, & pebbles'); |
||
11274 | * // => ['fred', 'barney', 'pebbles'] |
||
11275 | * |
||
11276 | * _.words('fred, barney, & pebbles', /[^, ]+/g); |
||
11277 | * // => ['fred', 'barney', '&', 'pebbles'] |
||
11278 | */ |
||
11279 | function words(string, pattern, guard) { |
||
11280 | if (guard && isIterateeCall(string, pattern, guard)) { |
||
11281 | pattern = undefined; |
||
11282 | } |
||
11283 | string = baseToString(string); |
||
11284 | return string.match(pattern || reWords) || []; |
||
11285 | } |
||
11286 | |||
11287 | /*------------------------------------------------------------------------*/ |
||
11288 | |||
11289 | /** |
||
11290 | * Attempts to invoke `func`, returning either the result or the caught error |
||
11291 | * object. Any additional arguments are provided to `func` when it's invoked. |
||
11292 | * |
||
11293 | * @static |
||
11294 | * @memberOf _ |
||
11295 | * @category Utility |
||
11296 | * @param {Function} func The function to attempt. |
||
11297 | * @returns {*} Returns the `func` result or error object. |
||
11298 | * @example |
||
11299 | * |
||
11300 | * // avoid throwing errors for invalid selectors |
||
11301 | * var elements = _.attempt(function(selector) { |
||
11302 | * return document.querySelectorAll(selector); |
||
11303 | * }, '>_>'); |
||
11304 | * |
||
11305 | * if (_.isError(elements)) { |
||
11306 | * elements = []; |
||
11307 | * } |
||
11308 | */ |
||
11309 | var attempt = restParam(function(func, args) { |
||
11310 | try { |
||
11311 | return func.apply(undefined, args); |
||
11312 | } catch(e) { |
||
11313 | return isError(e) ? e : new Error(e); |
||
11314 | } |
||
11315 | }); |
||
11316 | |||
11317 | /** |
||
11318 | * Creates a function that invokes `func` with the `this` binding of `thisArg` |
||
11319 | * and arguments of the created function. If `func` is a property name the |
||
11320 | * created callback returns the property value for a given element. If `func` |
||
11321 | * is an object the created callback returns `true` for elements that contain |
||
11322 | * the equivalent object properties, otherwise it returns `false`. |
||
11323 | * |
||
11324 | * @static |
||
11325 | * @memberOf _ |
||
11326 | * @alias iteratee |
||
11327 | * @category Utility |
||
11328 | * @param {*} [func=_.identity] The value to convert to a callback. |
||
11329 | * @param {*} [thisArg] The `this` binding of `func`. |
||
11330 | * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. |
||
11331 | * @returns {Function} Returns the callback. |
||
11332 | * @example |
||
11333 | * |
||
11334 | * var users = [ |
||
11335 | * { 'user': 'barney', 'age': 36 }, |
||
11336 | * { 'user': 'fred', 'age': 40 } |
||
11337 | * ]; |
||
11338 | * |
||
11339 | * // wrap to create custom callback shorthands |
||
11340 | * _.callback = _.wrap(_.callback, function(callback, func, thisArg) { |
||
11341 | * var match = /^(.+?)__([gl]t)(.+)$/.exec(func); |
||
11342 | * if (!match) { |
||
11343 | * return callback(func, thisArg); |
||
11344 | * } |
||
11345 | * return function(object) { |
||
11346 | * return match[2] == 'gt' |
||
11347 | * ? object[match[1]] > match[3] |
||
11348 | * : object[match[1]] < match[3]; |
||
11349 | * }; |
||
11350 | * }); |
||
11351 | * |
||
11352 | * _.filter(users, 'age__gt36'); |
||
11353 | * // => [{ 'user': 'fred', 'age': 40 }] |
||
11354 | */ |
||
11355 | function callback(func, thisArg, guard) { |
||
11356 | if (guard && isIterateeCall(func, thisArg, guard)) { |
||
11357 | thisArg = undefined; |
||
11358 | } |
||
11359 | return isObjectLike(func) |
||
11360 | ? matches(func) |
||
11361 | : baseCallback(func, thisArg); |
||
11362 | } |
||
11363 | |||
11364 | /** |
||
11365 | * Creates a function that returns `value`. |
||
11366 | * |
||
11367 | * @static |
||
11368 | * @memberOf _ |
||
11369 | * @category Utility |
||
11370 | * @param {*} value The value to return from the new function. |
||
11371 | * @returns {Function} Returns the new function. |
||
11372 | * @example |
||
11373 | * |
||
11374 | * var object = { 'user': 'fred' }; |
||
11375 | * var getter = _.constant(object); |
||
11376 | * |
||
11377 | * getter() === object; |
||
11378 | * // => true |
||
11379 | */ |
||
11380 | function constant(value) { |
||
11381 | return function() { |
||
11382 | return value; |
||
11383 | }; |
||
11384 | } |
||
11385 | |||
11386 | /** |
||
11387 | * This method returns the first argument provided to it. |
||
11388 | * |
||
11389 | * @static |
||
11390 | * @memberOf _ |
||
11391 | * @category Utility |
||
11392 | * @param {*} value Any value. |
||
11393 | * @returns {*} Returns `value`. |
||
11394 | * @example |
||
11395 | * |
||
11396 | * var object = { 'user': 'fred' }; |
||
11397 | * |
||
11398 | * _.identity(object) === object; |
||
11399 | * // => true |
||
11400 | */ |
||
11401 | function identity(value) { |
||
11402 | return value; |
||
11403 | } |
||
11404 | |||
11405 | /** |
||
11406 | * Creates a function that performs a deep comparison between a given object |
||
11407 | * and `source`, returning `true` if the given object has equivalent property |
||
11408 | * values, else `false`. |
||
11409 | * |
||
11410 | * **Note:** This method supports comparing arrays, booleans, `Date` objects, |
||
11411 | * numbers, `Object` objects, regexes, and strings. Objects are compared by |
||
11412 | * their own, not inherited, enumerable properties. For comparing a single |
||
11413 | * own or inherited property value see `_.matchesProperty`. |
||
11414 | * |
||
11415 | * @static |
||
11416 | * @memberOf _ |
||
11417 | * @category Utility |
||
11418 | * @param {Object} source The object of property values to match. |
||
11419 | * @returns {Function} Returns the new function. |
||
11420 | * @example |
||
11421 | * |
||
11422 | * var users = [ |
||
11423 | * { 'user': 'barney', 'age': 36, 'active': true }, |
||
11424 | * { 'user': 'fred', 'age': 40, 'active': false } |
||
11425 | * ]; |
||
11426 | * |
||
11427 | * _.filter(users, _.matches({ 'age': 40, 'active': false })); |
||
11428 | * // => [{ 'user': 'fred', 'age': 40, 'active': false }] |
||
11429 | */ |
||
11430 | function matches(source) { |
||
11431 | return baseMatches(baseClone(source, true)); |
||
11432 | } |
||
11433 | |||
11434 | /** |
||
11435 | * Creates a function that compares the property value of `path` on a given |
||
11436 | * object to `value`. |
||
11437 | * |
||
11438 | * **Note:** This method supports comparing arrays, booleans, `Date` objects, |
||
11439 | * numbers, `Object` objects, regexes, and strings. Objects are compared by |
||
11440 | * their own, not inherited, enumerable properties. |
||
11441 | * |
||
11442 | * @static |
||
11443 | * @memberOf _ |
||
11444 | * @category Utility |
||
11445 | * @param {Array|string} path The path of the property to get. |
||
11446 | * @param {*} srcValue The value to match. |
||
11447 | * @returns {Function} Returns the new function. |
||
11448 | * @example |
||
11449 | * |
||
11450 | * var users = [ |
||
11451 | * { 'user': 'barney' }, |
||
11452 | * { 'user': 'fred' } |
||
11453 | * ]; |
||
11454 | * |
||
11455 | * _.find(users, _.matchesProperty('user', 'fred')); |
||
11456 | * // => { 'user': 'fred' } |
||
11457 | */ |
||
11458 | function matchesProperty(path, srcValue) { |
||
11459 | return baseMatchesProperty(path, baseClone(srcValue, true)); |
||
11460 | } |
||
11461 | |||
11462 | /** |
||
11463 | * Creates a function that invokes the method at `path` on a given object. |
||
11464 | * Any additional arguments are provided to the invoked method. |
||
11465 | * |
||
11466 | * @static |
||
11467 | * @memberOf _ |
||
11468 | * @category Utility |
||
11469 | * @param {Array|string} path The path of the method to invoke. |
||
11470 | * @param {...*} [args] The arguments to invoke the method with. |
||
11471 | * @returns {Function} Returns the new function. |
||
11472 | * @example |
||
11473 | * |
||
11474 | * var objects = [ |
||
11475 | * { 'a': { 'b': { 'c': _.constant(2) } } }, |
||
11476 | * { 'a': { 'b': { 'c': _.constant(1) } } } |
||
11477 | * ]; |
||
11478 | * |
||
11479 | * _.map(objects, _.method('a.b.c')); |
||
11480 | * // => [2, 1] |
||
11481 | * |
||
11482 | * _.invoke(_.sortBy(objects, _.method(['a', 'b', 'c'])), 'a.b.c'); |
||
11483 | * // => [1, 2] |
||
11484 | */ |
||
11485 | var method = restParam(function(path, args) { |
||
11486 | return function(object) { |
||
11487 | return invokePath(object, path, args); |
||
11488 | }; |
||
11489 | }); |
||
11490 | |||
11491 | /** |
||
11492 | * The opposite of `_.method`; this method creates a function that invokes |
||
11493 | * the method at a given path on `object`. Any additional arguments are |
||
11494 | * provided to the invoked method. |
||
11495 | * |
||
11496 | * @static |
||
11497 | * @memberOf _ |
||
11498 | * @category Utility |
||
11499 | * @param {Object} object The object to query. |
||
11500 | * @param {...*} [args] The arguments to invoke the method with. |
||
11501 | * @returns {Function} Returns the new function. |
||
11502 | * @example |
||
11503 | * |
||
11504 | * var array = _.times(3, _.constant), |
||
11505 | * object = { 'a': array, 'b': array, 'c': array }; |
||
11506 | * |
||
11507 | * _.map(['a[2]', 'c[0]'], _.methodOf(object)); |
||
11508 | * // => [2, 0] |
||
11509 | * |
||
11510 | * _.map([['a', '2'], ['c', '0']], _.methodOf(object)); |
||
11511 | * // => [2, 0] |
||
11512 | */ |
||
11513 | var methodOf = restParam(function(object, args) { |
||
11514 | return function(path) { |
||
11515 | return invokePath(object, path, args); |
||
11516 | }; |
||
11517 | }); |
||
11518 | |||
11519 | /** |
||
11520 | * Adds all own enumerable function properties of a source object to the |
||
11521 | * destination object. If `object` is a function then methods are added to |
||
11522 | * its prototype as well. |
||
11523 | * |
||
11524 | * **Note:** Use `_.runInContext` to create a pristine `lodash` function to |
||
11525 | * avoid conflicts caused by modifying the original. |
||
11526 | * |
||
11527 | * @static |
||
11528 | * @memberOf _ |
||
11529 | * @category Utility |
||
11530 | * @param {Function|Object} [object=lodash] The destination object. |
||
11531 | * @param {Object} source The object of functions to add. |
||
11532 | * @param {Object} [options] The options object. |
||
11533 | * @param {boolean} [options.chain=true] Specify whether the functions added |
||
11534 | * are chainable. |
||
11535 | * @returns {Function|Object} Returns `object`. |
||
11536 | * @example |
||
11537 | * |
||
11538 | * function vowels(string) { |
||
11539 | * return _.filter(string, function(v) { |
||
11540 | * return /[aeiou]/i.test(v); |
||
11541 | * }); |
||
11542 | * } |
||
11543 | * |
||
11544 | * _.mixin({ 'vowels': vowels }); |
||
11545 | * _.vowels('fred'); |
||
11546 | * // => ['e'] |
||
11547 | * |
||
11548 | * _('fred').vowels().value(); |
||
11549 | * // => ['e'] |
||
11550 | * |
||
11551 | * _.mixin({ 'vowels': vowels }, { 'chain': false }); |
||
11552 | * _('fred').vowels(); |
||
11553 | * // => ['e'] |
||
11554 | */ |
||
11555 | function mixin(object, source, options) { |
||
11556 | if (options == null) { |
||
11557 | var isObj = isObject(source), |
||
11558 | props = isObj ? keys(source) : undefined, |
||
11559 | methodNames = (props && props.length) ? baseFunctions(source, props) : undefined; |
||
11560 | |||
11561 | if (!(methodNames ? methodNames.length : isObj)) { |
||
11562 | methodNames = false; |
||
11563 | options = source; |
||
11564 | source = object; |
||
11565 | object = this; |
||
11566 | } |
||
11567 | } |
||
11568 | if (!methodNames) { |
||
11569 | methodNames = baseFunctions(source, keys(source)); |
||
11570 | } |
||
11571 | var chain = true, |
||
11572 | index = -1, |
||
11573 | isFunc = isFunction(object), |
||
11574 | length = methodNames.length; |
||
11575 | |||
11576 | if (options === false) { |
||
11577 | chain = false; |
||
11578 | } else if (isObject(options) && 'chain' in options) { |
||
11579 | chain = options.chain; |
||
11580 | } |
||
11581 | while (++index < length) { |
||
11582 | var methodName = methodNames[index], |
||
11583 | func = source[methodName]; |
||
11584 | |||
11585 | object[methodName] = func; |
||
11586 | if (isFunc) { |
||
11587 | object.prototype[methodName] = (function(func) { |
||
11588 | return function() { |
||
11589 | var chainAll = this.__chain__; |
||
11590 | if (chain || chainAll) { |
||
11591 | var result = object(this.__wrapped__), |
||
11592 | actions = result.__actions__ = arrayCopy(this.__actions__); |
||
11593 | |||
11594 | actions.push({ 'func': func, 'args': arguments, 'thisArg': object }); |
||
11595 | result.__chain__ = chainAll; |
||
11596 | return result; |
||
11597 | } |
||
11598 | return func.apply(object, arrayPush([this.value()], arguments)); |
||
11599 | }; |
||
11600 | }(func)); |
||
11601 | } |
||
11602 | } |
||
11603 | return object; |
||
11604 | } |
||
11605 | |||
11606 | /** |
||
11607 | * Reverts the `_` variable to its previous value and returns a reference to |
||
11608 | * the `lodash` function. |
||
11609 | * |
||
11610 | * @static |
||
11611 | * @memberOf _ |
||
11612 | * @category Utility |
||
11613 | * @returns {Function} Returns the `lodash` function. |
||
11614 | * @example |
||
11615 | * |
||
11616 | * var lodash = _.noConflict(); |
||
11617 | */ |
||
11618 | function noConflict() { |
||
11619 | root._ = oldDash; |
||
11620 | return this; |
||
11621 | } |
||
11622 | |||
11623 | /** |
||
11624 | * A no-operation function that returns `undefined` regardless of the |
||
11625 | * arguments it receives. |
||
11626 | * |
||
11627 | * @static |
||
11628 | * @memberOf _ |
||
11629 | * @category Utility |
||
11630 | * @example |
||
11631 | * |
||
11632 | * var object = { 'user': 'fred' }; |
||
11633 | * |
||
11634 | * _.noop(object) === undefined; |
||
11635 | * // => true |
||
11636 | */ |
||
11637 | function noop() { |
||
11638 | // No operation performed. |
||
11639 | } |
||
11640 | |||
11641 | /** |
||
11642 | * Creates a function that returns the property value at `path` on a |
||
11643 | * given object. |
||
11644 | * |
||
11645 | * @static |
||
11646 | * @memberOf _ |
||
11647 | * @category Utility |
||
11648 | * @param {Array|string} path The path of the property to get. |
||
11649 | * @returns {Function} Returns the new function. |
||
11650 | * @example |
||
11651 | * |
||
11652 | * var objects = [ |
||
11653 | * { 'a': { 'b': { 'c': 2 } } }, |
||
11654 | * { 'a': { 'b': { 'c': 1 } } } |
||
11655 | * ]; |
||
11656 | * |
||
11657 | * _.map(objects, _.property('a.b.c')); |
||
11658 | * // => [2, 1] |
||
11659 | * |
||
11660 | * _.pluck(_.sortBy(objects, _.property(['a', 'b', 'c'])), 'a.b.c'); |
||
11661 | * // => [1, 2] |
||
11662 | */ |
||
11663 | function property(path) { |
||
11664 | return isKey(path) ? baseProperty(path) : basePropertyDeep(path); |
||
11665 | } |
||
11666 | |||
11667 | /** |
||
11668 | * The opposite of `_.property`; this method creates a function that returns |
||
11669 | * the property value at a given path on `object`. |
||
11670 | * |
||
11671 | * @static |
||
11672 | * @memberOf _ |
||
11673 | * @category Utility |
||
11674 | * @param {Object} object The object to query. |
||
11675 | * @returns {Function} Returns the new function. |
||
11676 | * @example |
||
11677 | * |
||
11678 | * var array = [0, 1, 2], |
||
11679 | * object = { 'a': array, 'b': array, 'c': array }; |
||
11680 | * |
||
11681 | * _.map(['a[2]', 'c[0]'], _.propertyOf(object)); |
||
11682 | * // => [2, 0] |
||
11683 | * |
||
11684 | * _.map([['a', '2'], ['c', '0']], _.propertyOf(object)); |
||
11685 | * // => [2, 0] |
||
11686 | */ |
||
11687 | function propertyOf(object) { |
||
11688 | return function(path) { |
||
11689 | return baseGet(object, toPath(path), (path + '')); |
||
11690 | }; |
||
11691 | } |
||
11692 | |||
11693 | /** |
||
11694 | * Creates an array of numbers (positive and/or negative) progressing from |
||
11695 | * `start` up to, but not including, `end`. If `end` is not specified it's |
||
11696 | * set to `start` with `start` then set to `0`. If `end` is less than `start` |
||
11697 | * a zero-length range is created unless a negative `step` is specified. |
||
11698 | * |
||
11699 | * @static |
||
11700 | * @memberOf _ |
||
11701 | * @category Utility |
||
11702 | * @param {number} [start=0] The start of the range. |
||
11703 | * @param {number} end The end of the range. |
||
11704 | * @param {number} [step=1] The value to increment or decrement by. |
||
11705 | * @returns {Array} Returns the new array of numbers. |
||
11706 | * @example |
||
11707 | * |
||
11708 | * _.range(4); |
||
11709 | * // => [0, 1, 2, 3] |
||
11710 | * |
||
11711 | * _.range(1, 5); |
||
11712 | * // => [1, 2, 3, 4] |
||
11713 | * |
||
11714 | * _.range(0, 20, 5); |
||
11715 | * // => [0, 5, 10, 15] |
||
11716 | * |
||
11717 | * _.range(0, -4, -1); |
||
11718 | * // => [0, -1, -2, -3] |
||
11719 | * |
||
11720 | * _.range(1, 4, 0); |
||
11721 | * // => [1, 1, 1] |
||
11722 | * |
||
11723 | * _.range(0); |
||
11724 | * // => [] |
||
11725 | */ |
||
11726 | function range(start, end, step) { |
||
11727 | if (step && isIterateeCall(start, end, step)) { |
||
11728 | end = step = undefined; |
||
11729 | } |
||
11730 | start = +start || 0; |
||
11731 | step = step == null ? 1 : (+step || 0); |
||
11732 | |||
11733 | if (end == null) { |
||
11734 | end = start; |
||
11735 | start = 0; |
||
11736 | } else { |
||
11737 | end = +end || 0; |
||
11738 | } |
||
11739 | // Use `Array(length)` so engines like Chakra and V8 avoid slower modes. |
||
11740 | // See https://youtu.be/XAqIpGU8ZZk#t=17m25s for more details. |
||
11741 | var index = -1, |
||
11742 | length = nativeMax(nativeCeil((end - start) / (step || 1)), 0), |
||
11743 | result = Array(length); |
||
11744 | |||
11745 | while (++index < length) { |
||
11746 | result[index] = start; |
||
11747 | start += step; |
||
11748 | } |
||
11749 | return result; |
||
11750 | } |
||
11751 | |||
11752 | /** |
||
11753 | * Invokes the iteratee function `n` times, returning an array of the results |
||
11754 | * of each invocation. The `iteratee` is bound to `thisArg` and invoked with |
||
11755 | * one argument; (index). |
||
11756 | * |
||
11757 | * @static |
||
11758 | * @memberOf _ |
||
11759 | * @category Utility |
||
11760 | * @param {number} n The number of times to invoke `iteratee`. |
||
11761 | * @param {Function} [iteratee=_.identity] The function invoked per iteration. |
||
11762 | * @param {*} [thisArg] The `this` binding of `iteratee`. |
||
11763 | * @returns {Array} Returns the array of results. |
||
11764 | * @example |
||
11765 | * |
||
11766 | * var diceRolls = _.times(3, _.partial(_.random, 1, 6, false)); |
||
11767 | * // => [3, 6, 4] |
||
11768 | * |
||
11769 | * _.times(3, function(n) { |
||
11770 | * mage.castSpell(n); |
||
11771 | * }); |
||
11772 | * // => invokes `mage.castSpell(n)` three times with `n` of `0`, `1`, and `2` |
||
11773 | * |
||
11774 | * _.times(3, function(n) { |
||
11775 | * this.cast(n); |
||
11776 | * }, mage); |
||
11777 | * // => also invokes `mage.castSpell(n)` three times |
||
11778 | */ |
||
11779 | function times(n, iteratee, thisArg) { |
||
11780 | n = nativeFloor(n); |
||
11781 | |||
11782 | // Exit early to avoid a JSC JIT bug in Safari 8 |
||
11783 | // where `Array(0)` is treated as `Array(1)`. |
||
11784 | if (n < 1 || !nativeIsFinite(n)) { |
||
11785 | return []; |
||
11786 | } |
||
11787 | var index = -1, |
||
11788 | result = Array(nativeMin(n, MAX_ARRAY_LENGTH)); |
||
11789 | |||
11790 | iteratee = bindCallback(iteratee, thisArg, 1); |
||
11791 | while (++index < n) { |
||
11792 | if (index < MAX_ARRAY_LENGTH) { |
||
11793 | result[index] = iteratee(index); |
||
11794 | } else { |
||
11795 | iteratee(index); |
||
11796 | } |
||
11797 | } |
||
11798 | return result; |
||
11799 | } |
||
11800 | |||
11801 | /** |
||
11802 | * Generates a unique ID. If `prefix` is provided the ID is appended to it. |
||
11803 | * |
||
11804 | * @static |
||
11805 | * @memberOf _ |
||
11806 | * @category Utility |
||
11807 | * @param {string} [prefix] The value to prefix the ID with. |
||
11808 | * @returns {string} Returns the unique ID. |
||
11809 | * @example |
||
11810 | * |
||
11811 | * _.uniqueId('contact_'); |
||
11812 | * // => 'contact_104' |
||
11813 | * |
||
11814 | * _.uniqueId(); |
||
11815 | * // => '105' |
||
11816 | */ |
||
11817 | function uniqueId(prefix) { |
||
11818 | var id = ++idCounter; |
||
11819 | return baseToString(prefix) + id; |
||
11820 | } |
||
11821 | |||
11822 | /*------------------------------------------------------------------------*/ |
||
11823 | |||
11824 | /** |
||
11825 | * Adds two numbers. |
||
11826 | * |
||
11827 | * @static |
||
11828 | * @memberOf _ |
||
11829 | * @category Math |
||
11830 | * @param {number} augend The first number to add. |
||
11831 | * @param {number} addend The second number to add. |
||
11832 | * @returns {number} Returns the sum. |
||
11833 | * @example |
||
11834 | * |
||
11835 | * _.add(6, 4); |
||
11836 | * // => 10 |
||
11837 | */ |
||
11838 | function add(augend, addend) { |
||
11839 | return (+augend || 0) + (+addend || 0); |
||
11840 | } |
||
11841 | |||
11842 | /** |
||
11843 | * Calculates `n` rounded up to `precision`. |
||
11844 | * |
||
11845 | * @static |
||
11846 | * @memberOf _ |
||
11847 | * @category Math |
||
11848 | * @param {number} n The number to round up. |
||
11849 | * @param {number} [precision=0] The precision to round up to. |
||
11850 | * @returns {number} Returns the rounded up number. |
||
11851 | * @example |
||
11852 | * |
||
11853 | * _.ceil(4.006); |
||
11854 | * // => 5 |
||
11855 | * |
||
11856 | * _.ceil(6.004, 2); |
||
11857 | * // => 6.01 |
||
11858 | * |
||
11859 | * _.ceil(6040, -2); |
||
11860 | * // => 6100 |
||
11861 | */ |
||
11862 | var ceil = createRound('ceil'); |
||
11863 | |||
11864 | /** |
||
11865 | * Calculates `n` rounded down to `precision`. |
||
11866 | * |
||
11867 | * @static |
||
11868 | * @memberOf _ |
||
11869 | * @category Math |
||
11870 | * @param {number} n The number to round down. |
||
11871 | * @param {number} [precision=0] The precision to round down to. |
||
11872 | * @returns {number} Returns the rounded down number. |
||
11873 | * @example |
||
11874 | * |
||
11875 | * _.floor(4.006); |
||
11876 | * // => 4 |
||
11877 | * |
||
11878 | * _.floor(0.046, 2); |
||
11879 | * // => 0.04 |
||
11880 | * |
||
11881 | * _.floor(4060, -2); |
||
11882 | * // => 4000 |
||
11883 | */ |
||
11884 | var floor = createRound('floor'); |
||
11885 | |||
11886 | /** |
||
11887 | * Gets the maximum value of `collection`. If `collection` is empty or falsey |
||
11888 | * `-Infinity` is returned. If an iteratee function is provided it's invoked |
||
11889 | * for each value in `collection` to generate the criterion by which the value |
||
11890 | * is ranked. The `iteratee` is bound to `thisArg` and invoked with three |
||
11891 | * arguments: (value, index, collection). |
||
11892 | * |
||
11893 | * If a property name is provided for `iteratee` the created `_.property` |
||
11894 | * style callback returns the property value of the given element. |
||
11895 | * |
||
11896 | * If a value is also provided for `thisArg` the created `_.matchesProperty` |
||
11897 | * style callback returns `true` for elements that have a matching property |
||
11898 | * value, else `false`. |
||
11899 | * |
||
11900 | * If an object is provided for `iteratee` the created `_.matches` style |
||
11901 | * callback returns `true` for elements that have the properties of the given |
||
11902 | * object, else `false`. |
||
11903 | * |
||
11904 | * @static |
||
11905 | * @memberOf _ |
||
11906 | * @category Math |
||
11907 | * @param {Array|Object|string} collection The collection to iterate over. |
||
11908 | * @param {Function|Object|string} [iteratee] The function invoked per iteration. |
||
11909 | * @param {*} [thisArg] The `this` binding of `iteratee`. |
||
11910 | * @returns {*} Returns the maximum value. |
||
11911 | * @example |
||
11912 | * |
||
11913 | * _.max([4, 2, 8, 6]); |
||
11914 | * // => 8 |
||
11915 | * |
||
11916 | * _.max([]); |
||
11917 | * // => -Infinity |
||
11918 | * |
||
11919 | * var users = [ |
||
11920 | * { 'user': 'barney', 'age': 36 }, |
||
11921 | * { 'user': 'fred', 'age': 40 } |
||
11922 | * ]; |
||
11923 | * |
||
11924 | * _.max(users, function(chr) { |
||
11925 | * return chr.age; |
||
11926 | * }); |
||
11927 | * // => { 'user': 'fred', 'age': 40 } |
||
11928 | * |
||
11929 | * // using the `_.property` callback shorthand |
||
11930 | * _.max(users, 'age'); |
||
11931 | * // => { 'user': 'fred', 'age': 40 } |
||
11932 | */ |
||
11933 | var max = createExtremum(gt, NEGATIVE_INFINITY); |
||
11934 | |||
11935 | /** |
||
11936 | * Gets the minimum value of `collection`. If `collection` is empty or falsey |
||
11937 | * `Infinity` is returned. If an iteratee function is provided it's invoked |
||
11938 | * for each value in `collection` to generate the criterion by which the value |
||
11939 | * is ranked. The `iteratee` is bound to `thisArg` and invoked with three |
||
11940 | * arguments: (value, index, collection). |
||
11941 | * |
||
11942 | * If a property name is provided for `iteratee` the created `_.property` |
||
11943 | * style callback returns the property value of the given element. |
||
11944 | * |
||
11945 | * If a value is also provided for `thisArg` the created `_.matchesProperty` |
||
11946 | * style callback returns `true` for elements that have a matching property |
||
11947 | * value, else `false`. |
||
11948 | * |
||
11949 | * If an object is provided for `iteratee` the created `_.matches` style |
||
11950 | * callback returns `true` for elements that have the properties of the given |
||
11951 | * object, else `false`. |
||
11952 | * |
||
11953 | * @static |
||
11954 | * @memberOf _ |
||
11955 | * @category Math |
||
11956 | * @param {Array|Object|string} collection The collection to iterate over. |
||
11957 | * @param {Function|Object|string} [iteratee] The function invoked per iteration. |
||
11958 | * @param {*} [thisArg] The `this` binding of `iteratee`. |
||
11959 | * @returns {*} Returns the minimum value. |
||
11960 | * @example |
||
11961 | * |
||
11962 | * _.min([4, 2, 8, 6]); |
||
11963 | * // => 2 |
||
11964 | * |
||
11965 | * _.min([]); |
||
11966 | * // => Infinity |
||
11967 | * |
||
11968 | * var users = [ |
||
11969 | * { 'user': 'barney', 'age': 36 }, |
||
11970 | * { 'user': 'fred', 'age': 40 } |
||
11971 | * ]; |
||
11972 | * |
||
11973 | * _.min(users, function(chr) { |
||
11974 | * return chr.age; |
||
11975 | * }); |
||
11976 | * // => { 'user': 'barney', 'age': 36 } |
||
11977 | * |
||
11978 | * // using the `_.property` callback shorthand |
||
11979 | * _.min(users, 'age'); |
||
11980 | * // => { 'user': 'barney', 'age': 36 } |
||
11981 | */ |
||
11982 | var min = createExtremum(lt, POSITIVE_INFINITY); |
||
11983 | |||
11984 | /** |
||
11985 | * Calculates `n` rounded to `precision`. |
||
11986 | * |
||
11987 | * @static |
||
11988 | * @memberOf _ |
||
11989 | * @category Math |
||
11990 | * @param {number} n The number to round. |
||
11991 | * @param {number} [precision=0] The precision to round to. |
||
11992 | * @returns {number} Returns the rounded number. |
||
11993 | * @example |
||
11994 | * |
||
11995 | * _.round(4.006); |
||
11996 | * // => 4 |
||
11997 | * |
||
11998 | * _.round(4.006, 2); |
||
11999 | * // => 4.01 |
||
12000 | * |
||
12001 | * _.round(4060, -2); |
||
12002 | * // => 4100 |
||
12003 | */ |
||
12004 | var round = createRound('round'); |
||
12005 | |||
12006 | /** |
||
12007 | * Gets the sum of the values in `collection`. |
||
12008 | * |
||
12009 | * @static |
||
12010 | * @memberOf _ |
||
12011 | * @category Math |
||
12012 | * @param {Array|Object|string} collection The collection to iterate over. |
||
12013 | * @param {Function|Object|string} [iteratee] The function invoked per iteration. |
||
12014 | * @param {*} [thisArg] The `this` binding of `iteratee`. |
||
12015 | * @returns {number} Returns the sum. |
||
12016 | * @example |
||
12017 | * |
||
12018 | * _.sum([4, 6]); |
||
12019 | * // => 10 |
||
12020 | * |
||
12021 | * _.sum({ 'a': 4, 'b': 6 }); |
||
12022 | * // => 10 |
||
12023 | * |
||
12024 | * var objects = [ |
||
12025 | * { 'n': 4 }, |
||
12026 | * { 'n': 6 } |
||
12027 | * ]; |
||
12028 | * |
||
12029 | * _.sum(objects, function(object) { |
||
12030 | * return object.n; |
||
12031 | * }); |
||
12032 | * // => 10 |
||
12033 | * |
||
12034 | * // using the `_.property` callback shorthand |
||
12035 | * _.sum(objects, 'n'); |
||
12036 | * // => 10 |
||
12037 | */ |
||
12038 | function sum(collection, iteratee, thisArg) { |
||
12039 | if (thisArg && isIterateeCall(collection, iteratee, thisArg)) { |
||
12040 | iteratee = undefined; |
||
12041 | } |
||
12042 | iteratee = getCallback(iteratee, thisArg, 3); |
||
12043 | return iteratee.length == 1 |
||
12044 | ? arraySum(isArray(collection) ? collection : toIterable(collection), iteratee) |
||
12045 | : baseSum(collection, iteratee); |
||
12046 | } |
||
12047 | |||
12048 | /*------------------------------------------------------------------------*/ |
||
12049 | |||
12050 | // Ensure wrappers are instances of `baseLodash`. |
||
12051 | lodash.prototype = baseLodash.prototype; |
||
12052 | |||
12053 | LodashWrapper.prototype = baseCreate(baseLodash.prototype); |
||
12054 | LodashWrapper.prototype.constructor = LodashWrapper; |
||
12055 | |||
12056 | LazyWrapper.prototype = baseCreate(baseLodash.prototype); |
||
12057 | LazyWrapper.prototype.constructor = LazyWrapper; |
||
12058 | |||
12059 | // Add functions to the `Map` cache. |
||
12060 | MapCache.prototype['delete'] = mapDelete; |
||
12061 | MapCache.prototype.get = mapGet; |
||
12062 | MapCache.prototype.has = mapHas; |
||
12063 | MapCache.prototype.set = mapSet; |
||
12064 | |||
12065 | // Add functions to the `Set` cache. |
||
12066 | SetCache.prototype.push = cachePush; |
||
12067 | |||
12068 | // Assign cache to `_.memoize`. |
||
12069 | memoize.Cache = MapCache; |
||
12070 | |||
12071 | // Add functions that return wrapped values when chaining. |
||
12072 | lodash.after = after; |
||
12073 | lodash.ary = ary; |
||
12074 | lodash.assign = assign; |
||
12075 | lodash.at = at; |
||
12076 | lodash.before = before; |
||
12077 | lodash.bind = bind; |
||
12078 | lodash.bindAll = bindAll; |
||
12079 | lodash.bindKey = bindKey; |
||
12080 | lodash.callback = callback; |
||
12081 | lodash.chain = chain; |
||
12082 | lodash.chunk = chunk; |
||
12083 | lodash.compact = compact; |
||
12084 | lodash.constant = constant; |
||
12085 | lodash.countBy = countBy; |
||
12086 | lodash.create = create; |
||
12087 | lodash.curry = curry; |
||
12088 | lodash.curryRight = curryRight; |
||
12089 | lodash.debounce = debounce; |
||
12090 | lodash.defaults = defaults; |
||
12091 | lodash.defaultsDeep = defaultsDeep; |
||
12092 | lodash.defer = defer; |
||
12093 | lodash.delay = delay; |
||
12094 | lodash.difference = difference; |
||
12095 | lodash.drop = drop; |
||
12096 | lodash.dropRight = dropRight; |
||
12097 | lodash.dropRightWhile = dropRightWhile; |
||
12098 | lodash.dropWhile = dropWhile; |
||
12099 | lodash.fill = fill; |
||
12100 | lodash.filter = filter; |
||
12101 | lodash.flatten = flatten; |
||
12102 | lodash.flattenDeep = flattenDeep; |
||
12103 | lodash.flow = flow; |
||
12104 | lodash.flowRight = flowRight; |
||
12105 | lodash.forEach = forEach; |
||
12106 | lodash.forEachRight = forEachRight; |
||
12107 | lodash.forIn = forIn; |
||
12108 | lodash.forInRight = forInRight; |
||
12109 | lodash.forOwn = forOwn; |
||
12110 | lodash.forOwnRight = forOwnRight; |
||
12111 | lodash.functions = functions; |
||
12112 | lodash.groupBy = groupBy; |
||
12113 | lodash.indexBy = indexBy; |
||
12114 | lodash.initial = initial; |
||
12115 | lodash.intersection = intersection; |
||
12116 | lodash.invert = invert; |
||
12117 | lodash.invoke = invoke; |
||
12118 | lodash.keys = keys; |
||
12119 | lodash.keysIn = keysIn; |
||
12120 | lodash.map = map; |
||
12121 | lodash.mapKeys = mapKeys; |
||
12122 | lodash.mapValues = mapValues; |
||
12123 | lodash.matches = matches; |
||
12124 | lodash.matchesProperty = matchesProperty; |
||
12125 | lodash.memoize = memoize; |
||
12126 | lodash.merge = merge; |
||
12127 | lodash.method = method; |
||
12128 | lodash.methodOf = methodOf; |
||
12129 | lodash.mixin = mixin; |
||
12130 | lodash.modArgs = modArgs; |
||
12131 | lodash.negate = negate; |
||
12132 | lodash.omit = omit; |
||
12133 | lodash.once = once; |
||
12134 | lodash.pairs = pairs; |
||
12135 | lodash.partial = partial; |
||
12136 | lodash.partialRight = partialRight; |
||
12137 | lodash.partition = partition; |
||
12138 | lodash.pick = pick; |
||
12139 | lodash.pluck = pluck; |
||
12140 | lodash.property = property; |
||
12141 | lodash.propertyOf = propertyOf; |
||
12142 | lodash.pull = pull; |
||
12143 | lodash.pullAt = pullAt; |
||
12144 | lodash.range = range; |
||
12145 | lodash.rearg = rearg; |
||
12146 | lodash.reject = reject; |
||
12147 | lodash.remove = remove; |
||
12148 | lodash.rest = rest; |
||
12149 | lodash.restParam = restParam; |
||
12150 | lodash.set = set; |
||
12151 | lodash.shuffle = shuffle; |
||
12152 | lodash.slice = slice; |
||
12153 | lodash.sortBy = sortBy; |
||
12154 | lodash.sortByAll = sortByAll; |
||
12155 | lodash.sortByOrder = sortByOrder; |
||
12156 | lodash.spread = spread; |
||
12157 | lodash.take = take; |
||
12158 | lodash.takeRight = takeRight; |
||
12159 | lodash.takeRightWhile = takeRightWhile; |
||
12160 | lodash.takeWhile = takeWhile; |
||
12161 | lodash.tap = tap; |
||
12162 | lodash.throttle = throttle; |
||
12163 | lodash.thru = thru; |
||
12164 | lodash.times = times; |
||
12165 | lodash.toArray = toArray; |
||
12166 | lodash.toPlainObject = toPlainObject; |
||
12167 | lodash.transform = transform; |
||
12168 | lodash.union = union; |
||
12169 | lodash.uniq = uniq; |
||
12170 | lodash.unzip = unzip; |
||
12171 | lodash.unzipWith = unzipWith; |
||
12172 | lodash.values = values; |
||
12173 | lodash.valuesIn = valuesIn; |
||
12174 | lodash.where = where; |
||
12175 | lodash.without = without; |
||
12176 | lodash.wrap = wrap; |
||
12177 | lodash.xor = xor; |
||
12178 | lodash.zip = zip; |
||
12179 | lodash.zipObject = zipObject; |
||
12180 | lodash.zipWith = zipWith; |
||
12181 | |||
12182 | // Add aliases. |
||
12183 | lodash.backflow = flowRight; |
||
12184 | lodash.collect = map; |
||
12185 | lodash.compose = flowRight; |
||
12186 | lodash.each = forEach; |
||
12187 | lodash.eachRight = forEachRight; |
||
12188 | lodash.extend = assign; |
||
12189 | lodash.iteratee = callback; |
||
12190 | lodash.methods = functions; |
||
12191 | lodash.object = zipObject; |
||
12192 | lodash.select = filter; |
||
12193 | lodash.tail = rest; |
||
12194 | lodash.unique = uniq; |
||
12195 | |||
12196 | // Add functions to `lodash.prototype`. |
||
12197 | mixin(lodash, lodash); |
||
12198 | |||
12199 | /*------------------------------------------------------------------------*/ |
||
12200 | |||
12201 | // Add functions that return unwrapped values when chaining. |
||
12202 | lodash.add = add; |
||
12203 | lodash.attempt = attempt; |
||
12204 | lodash.camelCase = camelCase; |
||
12205 | lodash.capitalize = capitalize; |
||
12206 | lodash.ceil = ceil; |
||
12207 | lodash.clone = clone; |
||
12208 | lodash.cloneDeep = cloneDeep; |
||
12209 | lodash.deburr = deburr; |
||
12210 | lodash.endsWith = endsWith; |
||
12211 | lodash.escape = escape; |
||
12212 | lodash.escapeRegExp = escapeRegExp; |
||
12213 | lodash.every = every; |
||
12214 | lodash.find = find; |
||
12215 | lodash.findIndex = findIndex; |
||
12216 | lodash.findKey = findKey; |
||
12217 | lodash.findLast = findLast; |
||
12218 | lodash.findLastIndex = findLastIndex; |
||
12219 | lodash.findLastKey = findLastKey; |
||
12220 | lodash.findWhere = findWhere; |
||
12221 | lodash.first = first; |
||
12222 | lodash.floor = floor; |
||
12223 | lodash.get = get; |
||
12224 | lodash.gt = gt; |
||
12225 | lodash.gte = gte; |
||
12226 | lodash.has = has; |
||
12227 | lodash.identity = identity; |
||
12228 | lodash.includes = includes; |
||
12229 | lodash.indexOf = indexOf; |
||
12230 | lodash.inRange = inRange; |
||
12231 | lodash.isArguments = isArguments; |
||
12232 | lodash.isArray = isArray; |
||
12233 | lodash.isBoolean = isBoolean; |
||
12234 | lodash.isDate = isDate; |
||
12235 | lodash.isElement = isElement; |
||
12236 | lodash.isEmpty = isEmpty; |
||
12237 | lodash.isEqual = isEqual; |
||
12238 | lodash.isError = isError; |
||
12239 | lodash.isFinite = isFinite; |
||
12240 | lodash.isFunction = isFunction; |
||
12241 | lodash.isMatch = isMatch; |
||
12242 | lodash.isNaN = isNaN; |
||
12243 | lodash.isNative = isNative; |
||
12244 | lodash.isNull = isNull; |
||
12245 | lodash.isNumber = isNumber; |
||
12246 | lodash.isObject = isObject; |
||
12247 | lodash.isPlainObject = isPlainObject; |
||
12248 | lodash.isRegExp = isRegExp; |
||
12249 | lodash.isString = isString; |
||
12250 | lodash.isTypedArray = isTypedArray; |
||
12251 | lodash.isUndefined = isUndefined; |
||
12252 | lodash.kebabCase = kebabCase; |
||
12253 | lodash.last = last; |
||
12254 | lodash.lastIndexOf = lastIndexOf; |
||
12255 | lodash.lt = lt; |
||
12256 | lodash.lte = lte; |
||
12257 | lodash.max = max; |
||
12258 | lodash.min = min; |
||
12259 | lodash.noConflict = noConflict; |
||
12260 | lodash.noop = noop; |
||
12261 | lodash.now = now; |
||
12262 | lodash.pad = pad; |
||
12263 | lodash.padLeft = padLeft; |
||
12264 | lodash.padRight = padRight; |
||
12265 | lodash.parseInt = parseInt; |
||
12266 | lodash.random = random; |
||
12267 | lodash.reduce = reduce; |
||
12268 | lodash.reduceRight = reduceRight; |
||
12269 | lodash.repeat = repeat; |
||
12270 | lodash.result = result; |
||
12271 | lodash.round = round; |
||
12272 | lodash.runInContext = runInContext; |
||
12273 | lodash.size = size; |
||
12274 | lodash.snakeCase = snakeCase; |
||
12275 | lodash.some = some; |
||
12276 | lodash.sortedIndex = sortedIndex; |
||
12277 | lodash.sortedLastIndex = sortedLastIndex; |
||
12278 | lodash.startCase = startCase; |
||
12279 | lodash.startsWith = startsWith; |
||
12280 | lodash.sum = sum; |
||
12281 | lodash.template = template; |
||
12282 | lodash.trim = trim; |
||
12283 | lodash.trimLeft = trimLeft; |
||
12284 | lodash.trimRight = trimRight; |
||
12285 | lodash.trunc = trunc; |
||
12286 | lodash.unescape = unescape; |
||
12287 | lodash.uniqueId = uniqueId; |
||
12288 | lodash.words = words; |
||
12289 | |||
12290 | // Add aliases. |
||
12291 | lodash.all = every; |
||
12292 | lodash.any = some; |
||
12293 | lodash.contains = includes; |
||
12294 | lodash.eq = isEqual; |
||
12295 | lodash.detect = find; |
||
12296 | lodash.foldl = reduce; |
||
12297 | lodash.foldr = reduceRight; |
||
12298 | lodash.head = first; |
||
12299 | lodash.include = includes; |
||
12300 | lodash.inject = reduce; |
||
12301 | |||
12302 | mixin(lodash, (function() { |
||
12303 | var source = {}; |
||
12304 | baseForOwn(lodash, function(func, methodName) { |
||
12305 | if (!lodash.prototype[methodName]) { |
||
12306 | source[methodName] = func; |
||
12307 | } |
||
12308 | }); |
||
12309 | return source; |
||
12310 | }()), false); |
||
12311 | |||
12312 | /*------------------------------------------------------------------------*/ |
||
12313 | |||
12314 | // Add functions capable of returning wrapped and unwrapped values when chaining. |
||
12315 | lodash.sample = sample; |
||
12316 | |||
12317 | lodash.prototype.sample = function(n) { |
||
12318 | if (!this.__chain__ && n == null) { |
||
12319 | return sample(this.value()); |
||
12320 | } |
||
12321 | return this.thru(function(value) { |
||
12322 | return sample(value, n); |
||
12323 | }); |
||
12324 | }; |
||
12325 | |||
12326 | /*------------------------------------------------------------------------*/ |
||
12327 | |||
12328 | /** |
||
12329 | * The semantic version number. |
||
12330 | * |
||
12331 | * @static |
||
12332 | * @memberOf _ |
||
12333 | * @type string |
||
12334 | */ |
||
12335 | lodash.VERSION = VERSION; |
||
12336 | |||
12337 | // Assign default placeholders. |
||
12338 | arrayEach(['bind', 'bindKey', 'curry', 'curryRight', 'partial', 'partialRight'], function(methodName) { |
||
12339 | lodash[methodName].placeholder = lodash; |
||
12340 | }); |
||
12341 | |||
12342 | // Add `LazyWrapper` methods for `_.drop` and `_.take` variants. |
||
12343 | arrayEach(['drop', 'take'], function(methodName, index) { |
||
12344 | LazyWrapper.prototype[methodName] = function(n) { |
||
12345 | var filtered = this.__filtered__; |
||
12346 | if (filtered && !index) { |
||
12347 | return new LazyWrapper(this); |
||
12348 | } |
||
12349 | n = n == null ? 1 : nativeMax(nativeFloor(n) || 0, 0); |
||
12350 | |||
12351 | var result = this.clone(); |
||
12352 | if (filtered) { |
||
12353 | result.__takeCount__ = nativeMin(result.__takeCount__, n); |
||
12354 | } else { |
||
12355 | result.__views__.push({ 'size': n, 'type': methodName + (result.__dir__ < 0 ? 'Right' : '') }); |
||
12356 | } |
||
12357 | return result; |
||
12358 | }; |
||
12359 | |||
12360 | LazyWrapper.prototype[methodName + 'Right'] = function(n) { |
||
12361 | return this.reverse()[methodName](n).reverse(); |
||
12362 | }; |
||
12363 | }); |
||
12364 | |||
12365 | // Add `LazyWrapper` methods that accept an `iteratee` value. |
||
12366 | arrayEach(['filter', 'map', 'takeWhile'], function(methodName, index) { |
||
12367 | var type = index + 1, |
||
12368 | isFilter = type != LAZY_MAP_FLAG; |
||
12369 | |||
12370 | LazyWrapper.prototype[methodName] = function(iteratee, thisArg) { |
||
12371 | var result = this.clone(); |
||
12372 | result.__iteratees__.push({ 'iteratee': getCallback(iteratee, thisArg, 1), 'type': type }); |
||
12373 | result.__filtered__ = result.__filtered__ || isFilter; |
||
12374 | return result; |
||
12375 | }; |
||
12376 | }); |
||
12377 | |||
12378 | // Add `LazyWrapper` methods for `_.first` and `_.last`. |
||
12379 | arrayEach(['first', 'last'], function(methodName, index) { |
||
12380 | var takeName = 'take' + (index ? 'Right' : ''); |
||
12381 | |||
12382 | LazyWrapper.prototype[methodName] = function() { |
||
12383 | return this[takeName](1).value()[0]; |
||
12384 | }; |
||
12385 | }); |
||
12386 | |||
12387 | // Add `LazyWrapper` methods for `_.initial` and `_.rest`. |
||
12388 | arrayEach(['initial', 'rest'], function(methodName, index) { |
||
12389 | var dropName = 'drop' + (index ? '' : 'Right'); |
||
12390 | |||
12391 | LazyWrapper.prototype[methodName] = function() { |
||
12392 | return this.__filtered__ ? new LazyWrapper(this) : this[dropName](1); |
||
12393 | }; |
||
12394 | }); |
||
12395 | |||
12396 | // Add `LazyWrapper` methods for `_.pluck` and `_.where`. |
||
12397 | arrayEach(['pluck', 'where'], function(methodName, index) { |
||
12398 | var operationName = index ? 'filter' : 'map', |
||
12399 | createCallback = index ? baseMatches : property; |
||
12400 | |||
12401 | LazyWrapper.prototype[methodName] = function(value) { |
||
12402 | return this[operationName](createCallback(value)); |
||
12403 | }; |
||
12404 | }); |
||
12405 | |||
12406 | LazyWrapper.prototype.compact = function() { |
||
12407 | return this.filter(identity); |
||
12408 | }; |
||
12409 | |||
12410 | LazyWrapper.prototype.reject = function(predicate, thisArg) { |
||
12411 | predicate = getCallback(predicate, thisArg, 1); |
||
12412 | return this.filter(function(value) { |
||
12413 | return !predicate(value); |
||
12414 | }); |
||
12415 | }; |
||
12416 | |||
12417 | LazyWrapper.prototype.slice = function(start, end) { |
||
12418 | start = start == null ? 0 : (+start || 0); |
||
12419 | |||
12420 | var result = this; |
||
12421 | if (result.__filtered__ && (start > 0 || end < 0)) { |
||
12422 | return new LazyWrapper(result); |
||
12423 | } |
||
12424 | if (start < 0) { |
||
12425 | result = result.takeRight(-start); |
||
12426 | } else if (start) { |
||
12427 | result = result.drop(start); |
||
12428 | } |
||
12429 | if (end !== undefined) { |
||
12430 | end = (+end || 0); |
||
12431 | result = end < 0 ? result.dropRight(-end) : result.take(end - start); |
||
12432 | } |
||
12433 | return result; |
||
12434 | }; |
||
12435 | |||
12436 | LazyWrapper.prototype.takeRightWhile = function(predicate, thisArg) { |
||
12437 | return this.reverse().takeWhile(predicate, thisArg).reverse(); |
||
12438 | }; |
||
12439 | |||
12440 | LazyWrapper.prototype.toArray = function() { |
||
12441 | return this.take(POSITIVE_INFINITY); |
||
12442 | }; |
||
12443 | |||
12444 | // Add `LazyWrapper` methods to `lodash.prototype`. |
||
12445 | baseForOwn(LazyWrapper.prototype, function(func, methodName) { |
||
12446 | var checkIteratee = /^(?:filter|map|reject)|While$/.test(methodName), |
||
12447 | retUnwrapped = /^(?:first|last)$/.test(methodName), |
||
12448 | lodashFunc = lodash[retUnwrapped ? ('take' + (methodName == 'last' ? 'Right' : '')) : methodName]; |
||
12449 | |||
12450 | if (!lodashFunc) { |
||
12451 | return; |
||
12452 | } |
||
12453 | lodash.prototype[methodName] = function() { |
||
12454 | var args = retUnwrapped ? [1] : arguments, |
||
12455 | chainAll = this.__chain__, |
||
12456 | value = this.__wrapped__, |
||
12457 | isHybrid = !!this.__actions__.length, |
||
12458 | isLazy = value instanceof LazyWrapper, |
||
12459 | iteratee = args[0], |
||
12460 | useLazy = isLazy || isArray(value); |
||
12461 | |||
12462 | if (useLazy && checkIteratee && typeof iteratee == 'function' && iteratee.length != 1) { |
||
12463 | // Avoid lazy use if the iteratee has a "length" value other than `1`. |
||
12464 | isLazy = useLazy = false; |
||
12465 | } |
||
12466 | var interceptor = function(value) { |
||
12467 | return (retUnwrapped && chainAll) |
||
12468 | ? lodashFunc(value, 1)[0] |
||
12469 | : lodashFunc.apply(undefined, arrayPush([value], args)); |
||
12470 | }; |
||
12471 | |||
12472 | var action = { 'func': thru, 'args': [interceptor], 'thisArg': undefined }, |
||
12473 | onlyLazy = isLazy && !isHybrid; |
||
12474 | |||
12475 | if (retUnwrapped && !chainAll) { |
||
12476 | if (onlyLazy) { |
||
12477 | value = value.clone(); |
||
12478 | value.__actions__.push(action); |
||
12479 | return func.call(value); |
||
12480 | } |
||
12481 | return lodashFunc.call(undefined, this.value())[0]; |
||
12482 | } |
||
12483 | if (!retUnwrapped && useLazy) { |
||
12484 | value = onlyLazy ? value : new LazyWrapper(this); |
||
12485 | var result = func.apply(value, args); |
||
12486 | result.__actions__.push(action); |
||
12487 | return new LodashWrapper(result, chainAll); |
||
12488 | } |
||
12489 | return this.thru(interceptor); |
||
12490 | }; |
||
12491 | }); |
||
12492 | |||
12493 | // Add `Array` and `String` methods to `lodash.prototype`. |
||
12494 | arrayEach(['join', 'pop', 'push', 'replace', 'shift', 'sort', 'splice', 'split', 'unshift'], function(methodName) { |
||
12495 | var protoFunc = (/^(?:replace|split)$/.test(methodName) ? stringProto : arrayProto)[methodName], |
||
12496 | chainName = /^(?:push|sort|unshift)$/.test(methodName) ? 'tap' : 'thru', |
||
12497 | fixObjects = !support.spliceObjects && /^(?:pop|shift|splice)$/.test(methodName), |
||
12498 | retUnwrapped = /^(?:join|pop|replace|shift)$/.test(methodName); |
||
12499 | |||
12500 | // Avoid array-like object bugs with `Array#shift` and `Array#splice` in |
||
12501 | // IE < 9, Firefox < 10, and RingoJS. |
||
12502 | var func = !fixObjects ? protoFunc : function() { |
||
12503 | var result = protoFunc.apply(this, arguments); |
||
12504 | if (this.length === 0) { |
||
12505 | delete this[0]; |
||
12506 | } |
||
12507 | return result; |
||
12508 | }; |
||
12509 | |||
12510 | lodash.prototype[methodName] = function() { |
||
12511 | var args = arguments; |
||
12512 | if (retUnwrapped && !this.__chain__) { |
||
12513 | return func.apply(this.value(), args); |
||
12514 | } |
||
12515 | return this[chainName](function(value) { |
||
12516 | return func.apply(value, args); |
||
12517 | }); |
||
12518 | }; |
||
12519 | }); |
||
12520 | |||
12521 | // Map minified function names to their real names. |
||
12522 | baseForOwn(LazyWrapper.prototype, function(func, methodName) { |
||
12523 | var lodashFunc = lodash[methodName]; |
||
12524 | if (lodashFunc) { |
||
12525 | var key = (lodashFunc.name + ''), |
||
12526 | names = realNames[key] || (realNames[key] = []); |
||
12527 | |||
12528 | names.push({ 'name': methodName, 'func': lodashFunc }); |
||
12529 | } |
||
12530 | }); |
||
12531 | |||
12532 | realNames[createHybridWrapper(undefined, BIND_KEY_FLAG).name] = [{ 'name': 'wrapper', 'func': undefined }]; |
||
12533 | |||
12534 | // Add functions to the lazy wrapper. |
||
12535 | LazyWrapper.prototype.clone = lazyClone; |
||
12536 | LazyWrapper.prototype.reverse = lazyReverse; |
||
12537 | LazyWrapper.prototype.value = lazyValue; |
||
12538 | |||
12539 | // Add chaining functions to the `lodash` wrapper. |
||
12540 | lodash.prototype.chain = wrapperChain; |
||
12541 | lodash.prototype.commit = wrapperCommit; |
||
12542 | lodash.prototype.concat = wrapperConcat; |
||
12543 | lodash.prototype.plant = wrapperPlant; |
||
12544 | lodash.prototype.reverse = wrapperReverse; |
||
12545 | lodash.prototype.toString = wrapperToString; |
||
12546 | lodash.prototype.run = lodash.prototype.toJSON = lodash.prototype.valueOf = lodash.prototype.value = wrapperValue; |
||
12547 | |||
12548 | // Add function aliases to the `lodash` wrapper. |
||
12549 | lodash.prototype.collect = lodash.prototype.map; |
||
12550 | lodash.prototype.head = lodash.prototype.first; |
||
12551 | lodash.prototype.select = lodash.prototype.filter; |
||
12552 | lodash.prototype.tail = lodash.prototype.rest; |
||
12553 | |||
12554 | return lodash; |
||
12555 | } |
||
12556 | |||
12557 | /*--------------------------------------------------------------------------*/ |
||
12558 | |||
12559 | // Export lodash. |
||
12560 | var _ = runInContext(); |
||
12561 | |||
12562 | // Some AMD build optimizers like r.js check for condition patterns like the following: |
||
12563 | if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) { |
||
12564 | // Expose lodash to the global object when an AMD loader is present to avoid |
||
12565 | // errors in cases where lodash is loaded by a script tag and not intended |
||
12566 | // as an AMD module. See http://requirejs.org/docs/errors.html#mismatch for |
||
12567 | // more details. |
||
12568 | root._ = _; |
||
12569 | |||
12570 | // Define as an anonymous module so, through path mapping, it can be |
||
12571 | // referenced as the "underscore" module. |
||
12572 | define(function() { |
||
12573 | return _; |
||
12574 | }); |
||
12575 | } |
||
12576 | // Check for `exports` after `define` in case a build optimizer adds an `exports` object. |
||
12577 | else if (freeExports && freeModule) { |
||
12578 | // Export for Node.js or RingoJS. |
||
12579 | if (moduleExports) { |
||
12580 | (freeModule.exports = _)._ = _; |
||
12581 | } |
||
12582 | // Export for Rhino with CommonJS support. |
||
12583 | else { |
||
12584 | freeExports._ = _; |
||
12585 | } |
||
12586 | } |
||
12587 | else { |
||
12588 | // Export for a browser or Rhino. |
||
12589 | root._ = _; |
||
12590 | } |
||
12591 | }.call(this)); |
||
12592 |